├── .gitignore
├── README.md
├── account
├── api
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── account
│ │ └── api
│ │ ├── AccountUrl.java
│ │ ├── constants
│ │ └── AccountFlowType.java
│ │ └── events
│ │ └── AskReduceBalance.java
├── core
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── akkafun
│ │ │ │ └── account
│ │ │ │ ├── context
│ │ │ │ └── AccountApplication.java
│ │ │ │ ├── dao
│ │ │ │ ├── AccountFlowRepository.java
│ │ │ │ ├── AccountFlowRepositoryCustom.java
│ │ │ │ ├── AccountFlowRepositoryImpl.java
│ │ │ │ ├── AccountRepository.java
│ │ │ │ ├── AccountRepositoryCustom.java
│ │ │ │ └── AccountRepositoryImpl.java
│ │ │ │ ├── domain
│ │ │ │ ├── Account.java
│ │ │ │ └── AccountFlow.java
│ │ │ │ ├── handler
│ │ │ │ ├── AskReduceBalanceHandler.java
│ │ │ │ └── UserCreatedHandler.java
│ │ │ │ ├── service
│ │ │ │ └── AccountService.java
│ │ │ │ └── web
│ │ │ │ └── AccountController.java
│ │ └── resources
│ │ │ ├── bootstrap.yml
│ │ │ └── logback.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── account
│ │ └── TestClass.java
├── docs
│ ├── account-service.pdm
│ └── account-service.sql
└── pom.xml
├── apiutils
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── akkafun
│ └── base
│ ├── Constants.java
│ ├── api
│ ├── BooleanWrapper.java
│ ├── CommonErrorCode.java
│ ├── Error.java
│ └── ErrorCode.java
│ ├── event
│ ├── constants
│ │ ├── EventType.java
│ │ ├── FailureInfo.java
│ │ └── FailureReason.java
│ └── domain
│ │ ├── AskEvent.java
│ │ ├── AskResponseEvent.java
│ │ ├── BaseEvent.java
│ │ ├── NotifyEvent.java
│ │ ├── Revokable.java
│ │ └── RevokeAskEvent.java
│ └── exception
│ ├── AppBusinessException.java
│ ├── BaseException.java
│ ├── RemoteCallException.java
│ └── ServiceUnavailableException.java
├── common
├── docs
│ ├── common.pdm
│ └── common.sql
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── common
│ │ ├── dao
│ │ └── AbstractRepository.java
│ │ ├── domain
│ │ ├── AuditEntity.java
│ │ ├── LockableEntity.java
│ │ └── VersionEntity.java
│ │ ├── event
│ │ ├── AskEventCallback.java
│ │ ├── AskParameter.java
│ │ ├── AskParameterBuilder.java
│ │ ├── EventRegistry.java
│ │ ├── EventUtils.java
│ │ ├── config
│ │ │ ├── EventConfiguration.java
│ │ │ └── InitBindProducer.java
│ │ ├── constant
│ │ │ ├── AskEventStatus.java
│ │ │ ├── EventCategory.java
│ │ │ └── ProcessStatus.java
│ │ ├── dao
│ │ │ ├── AskRequestEventPublishRepository.java
│ │ │ ├── AskRequestEventPublishRepositoryCustom.java
│ │ │ ├── AskRequestEventPublishRepositoryImpl.java
│ │ │ ├── AskResponseEventPublishRepository.java
│ │ │ ├── AskResponseEventPublishRepositoryCustom.java
│ │ │ ├── AskResponseEventPublishRepositoryImpl.java
│ │ │ ├── EventProcessRepository.java
│ │ │ ├── EventProcessRepositoryCustom.java
│ │ │ ├── EventProcessRepositoryImpl.java
│ │ │ ├── EventPublishRepository.java
│ │ │ ├── EventWatchProcessRepository.java
│ │ │ ├── EventWatchProcessRepositoryCustom.java
│ │ │ ├── EventWatchProcessRepositoryImpl.java
│ │ │ ├── EventWatchRepository.java
│ │ │ ├── EventWatchRepositoryCustom.java
│ │ │ ├── EventWatchRepositoryImpl.java
│ │ │ ├── NotifyEventPublishRepository.java
│ │ │ ├── NotifyEventPublishRepositoryCustom.java
│ │ │ ├── NotifyEventPublishRepositoryImpl.java
│ │ │ ├── RevokeAskEventPublishRepository.java
│ │ │ ├── RevokeAskEventPublishRepositoryCustom.java
│ │ │ └── RevokeAskEventPublishRepositoryImpl.java
│ │ ├── domain
│ │ │ ├── AskRequestEventPublish.java
│ │ │ ├── AskResponseEventPublish.java
│ │ │ ├── EventProcess.java
│ │ │ ├── EventPublish.java
│ │ │ ├── EventWatch.java
│ │ │ ├── EventWatchProcess.java
│ │ │ ├── NotifyEventPublish.java
│ │ │ └── RevokeAskEventPublish.java
│ │ ├── handler
│ │ │ ├── AskEventHandler.java
│ │ │ ├── NotifyEventHandler.java
│ │ │ └── RevokableAskEventHandler.java
│ │ ├── scheduler
│ │ │ └── EventScheduler.java
│ │ └── service
│ │ │ ├── EventActivator.java
│ │ │ ├── EventBus.java
│ │ │ ├── EventHandlerExecutor.java
│ │ │ ├── EventPublishService.java
│ │ │ └── EventWatchService.java
│ │ ├── exception
│ │ └── EventException.java
│ │ ├── scheduler
│ │ ├── ZkCoordinateScheduledExecutor.java
│ │ ├── ZkSchedulerCoordinator.java
│ │ └── config
│ │ │ └── SchedulerConfiguration.java
│ │ ├── spring
│ │ ├── ApplicationConstant.java
│ │ ├── ApplicationContextHolder.java
│ │ ├── BaseConfiguration.java
│ │ ├── ServiceClientConfiguration.java
│ │ ├── WebApplication.java
│ │ ├── cloud
│ │ │ └── stream
│ │ │ │ ├── CustomBinderAwareChannelResolver.java
│ │ │ │ └── CustomChannelBindingService.java
│ │ ├── mvc
│ │ │ ├── AppErrorController.java
│ │ │ └── AppExceptionHandlerController.java
│ │ └── utils
│ │ │ └── InnerClassPathScanningCandidateComponentProvider.java
│ │ └── test
│ │ ├── callbacks
│ │ ├── AskTestEventFirstCallback.java
│ │ ├── AskTestEventSecondCallback.java
│ │ ├── CallbackParam.java
│ │ └── UnitedTestEventCallback.java
│ │ ├── domain
│ │ ├── AskTestEvent.java
│ │ ├── NotifyFirstTestEvent.java
│ │ ├── NotifySecondTestEvent.java
│ │ └── RevokableAskTestEvent.java
│ │ └── handlers
│ │ ├── AskTestEventHandler.java
│ │ ├── NotifyFirstTestEventFirstHandler.java
│ │ ├── NotifyFirstTestEventSecondHandler.java
│ │ ├── NotifySecondTestEventHandler.java
│ │ └── RevokableAskTestEventHandler.java
│ └── test
│ └── java
│ └── com
│ └── akkafun
│ └── common
│ ├── event
│ ├── EventRegistryTest.java
│ ├── EventTestUtils.java
│ └── EventUtilsTest.java
│ └── test
│ ├── BaseControllerTest.java
│ └── BaseTest.java
├── config
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── akkafun
│ │ └── config
│ │ └── ConfigApplication.java
│ └── resources
│ └── application.yml
├── coupon
├── api
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── coupon
│ │ └── api
│ │ ├── CouponUrl.java
│ │ ├── constants
│ │ └── CouponState.java
│ │ ├── dtos
│ │ └── CouponDto.java
│ │ └── events
│ │ └── AskUseCoupon.java
├── core
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── akkafun
│ │ │ └── coupon
│ │ │ ├── context
│ │ │ └── CouponApplication.java
│ │ │ ├── dao
│ │ │ ├── CouponRepository.java
│ │ │ ├── CouponRepositoryCustom.java
│ │ │ └── CouponRepositoryImpl.java
│ │ │ ├── domain
│ │ │ └── Coupon.java
│ │ │ ├── handler
│ │ │ ├── AskUseCouponHandler.java
│ │ │ └── UserCreatedHandler.java
│ │ │ ├── service
│ │ │ └── CouponService.java
│ │ │ └── web
│ │ │ └── CouponController.java
│ │ └── resources
│ │ ├── bootstrap.yml
│ │ └── logback.xml
├── docs
│ ├── coupon-service.pdm
│ └── coupon-service.sql
└── pom.xml
├── docs
├── event.asta
└── init_database.sql
├── eureka
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── akkafun
│ │ └── eureka
│ │ └── EurekaApplication.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
├── integration-test
├── pom.xml
└── src
│ ├── main
│ └── resources
│ │ ├── application.yml
│ │ └── logback.xml
│ └── test
│ └── java
│ └── com
│ └── akkafun
│ └── integrationtest
│ ├── order
│ └── OrderIntegrationTest.java
│ └── test
│ ├── BaseIntegrationTest.java
│ └── IntegrationTestApplication.java
├── order
├── api
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── order
│ │ └── api
│ │ ├── OrderUrl.java
│ │ ├── constants
│ │ └── OrderStatus.java
│ │ ├── dtos
│ │ ├── OrderDto.java
│ │ ├── OrderItemDto.java
│ │ ├── PlaceOrderDto.java
│ │ └── PlaceOrderItemDto.java
│ │ └── events
│ │ └── OrderCreatePending.java
├── core
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── akkafun
│ │ │ │ └── order
│ │ │ │ ├── callback
│ │ │ │ └── OrderCreateCallback.java
│ │ │ │ ├── context
│ │ │ │ └── OrderApplication.java
│ │ │ │ ├── dao
│ │ │ │ ├── OrderCouponRepository.java
│ │ │ │ ├── OrderItemRepository.java
│ │ │ │ ├── OrderRepository.java
│ │ │ │ ├── OrderRepositoryCustom.java
│ │ │ │ └── OrderRepositoryImpl.java
│ │ │ │ ├── domain
│ │ │ │ ├── Order.java
│ │ │ │ ├── OrderCoupon.java
│ │ │ │ └── OrderItem.java
│ │ │ │ ├── service
│ │ │ │ ├── OrderService.java
│ │ │ │ └── gateway
│ │ │ │ │ ├── AccountClient.java
│ │ │ │ │ ├── AccountGateway.java
│ │ │ │ │ ├── CouponClient.java
│ │ │ │ │ ├── CouponGateway.java
│ │ │ │ │ ├── ProductClient.java
│ │ │ │ │ └── ProductGateway.java
│ │ │ │ ├── utils
│ │ │ │ └── OrderUtils.java
│ │ │ │ └── web
│ │ │ │ └── OrderController.java
│ │ └── resources
│ │ │ ├── bootstrap.yml
│ │ │ └── logback.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── order
│ │ ├── service
│ │ ├── OrderServiceTest.java
│ │ └── gateway
│ │ │ └── ProductGatewayTest.java
│ │ └── test
│ │ ├── OrderBaseControllerTest.java
│ │ ├── OrderBaseTest.java
│ │ └── TestOrderApplication.java
├── docs
│ ├── order-service.pdm
│ └── order-service.sql
└── pom.xml
├── pom.xml
├── product
├── api
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── product
│ │ └── api
│ │ ├── ProductUrl.java
│ │ └── dtos
│ │ └── ProductDto.java
├── core
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── akkafun
│ │ │ └── product
│ │ │ ├── context
│ │ │ └── ProductApplication.java
│ │ │ ├── dao
│ │ │ └── ProductRepository.java
│ │ │ ├── domain
│ │ │ └── Product.java
│ │ │ ├── service
│ │ │ └── ProductService.java
│ │ │ └── web
│ │ │ └── ProductController.java
│ │ └── resources
│ │ ├── bootstrap.yml
│ │ └── logback.xml
├── docs
│ ├── init-product.sql
│ ├── product-service.pdm
│ └── product-service.sql
└── pom.xml
├── turbine
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── akkafun
│ │ └── turbine
│ │ └── TurbineApplication.java
│ └── resources
│ └── application.yml
├── user
├── api
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ └── user
│ │ └── api
│ │ ├── UserErrorCode.java
│ │ ├── UserUrl.java
│ │ ├── dtos
│ │ ├── RegisterDto.java
│ │ └── UserDto.java
│ │ ├── events
│ │ └── UserCreated.java
│ │ └── utils
│ │ └── RegExpUtils.java
├── core
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── akkafun
│ │ │ │ └── user
│ │ │ │ ├── context
│ │ │ │ └── UserApplication.java
│ │ │ │ ├── dao
│ │ │ │ ├── UserRepository.java
│ │ │ │ ├── UserRepositoryCustom.java
│ │ │ │ └── UserRepositoryImpl.java
│ │ │ │ ├── domain
│ │ │ │ └── User.java
│ │ │ │ ├── service
│ │ │ │ └── UserService.java
│ │ │ │ └── web
│ │ │ │ └── UserController.java
│ │ └── resources
│ │ │ ├── bootstrap.yml
│ │ │ └── logback.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── akkafun
│ │ ├── common
│ │ └── event
│ │ │ ├── load
│ │ │ ├── FakeAskCouponUse.java
│ │ │ ├── FakeAskDeductBalance.java
│ │ │ ├── FakeAskEvent.java
│ │ │ ├── FakeEventBus.java
│ │ │ ├── FakeUnitedAskEventCallback.java
│ │ │ └── LoadEventClassTest.java
│ │ │ └── service
│ │ │ └── EventBusTest.java
│ │ └── user
│ │ ├── service
│ │ └── UserServiceTest.java
│ │ ├── test
│ │ ├── TestUserApplication.java
│ │ ├── UserBaseControllerTest.java
│ │ └── UserBaseTest.java
│ │ └── web
│ │ └── UserControllerTest.java
├── docs
│ ├── user-service.pdm
│ └── user-service.sql
└── pom.xml
└── utils
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── akkafun
│ └── common
│ └── utils
│ ├── CustomPreconditions.java
│ ├── JsonUtils.java
│ ├── PasswordHash.java
│ ├── SQLUtils.java
│ ├── StringUtils.java
│ ├── TestUtils.java
│ ├── UpdateByIdFunction.java
│ ├── ZkUtils.java
│ └── spring
│ ├── CustomRestTemplate.java
│ └── RestTemplateErrorHandler.java
└── test
└── java
└── com
└── akkafun
└── common
└── utils
└── StringUtilsTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | project/project
3 | project/target
4 | target
5 | tmp
6 | .history
7 | dist
8 | /.idea
9 | *.iml
10 | /out
11 | /.idea_modules
12 | /.classpath
13 | /.project
14 | /RUNNING_PID
15 | /.settings
16 | *.pdb
17 | **/development.conf
18 | **/application-log.*
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mysteam
2 |
3 | mysteam是一个Demo项目, 用来演示Spring Cloud与Netflix OSS在微服务系统中的使用.
4 |
5 | ######主要特点:
6 |
7 | 1. 使用eureka和Netflix Ribbon进行服务注册和服务发现.
8 |
9 | 2. 使用Spring Cloud Stream, zookeeper和kafka实现分布式事务.
10 |
11 | 3. 使用hystrix实现服务隔离, hystrix dashboard和turbine进行服务监控.
12 |
13 | 4. 使用Spring MVC和Swagger实现REST API.
14 |
15 | 5. 使用Spring Cloud Config实现配置集中管理.
16 |
17 | 详细介绍: [Spring Cloud与微服务](http://skaka.me/blog/2016/08/03/springcloud2/)
18 |
--------------------------------------------------------------------------------
/account/api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | account-service-api
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | account-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.akkafun.mysteam
19 | apiutils
20 | ${project.version}
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/account/api/src/main/java/com/akkafun/account/api/AccountUrl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/6.
5 | */
6 | public interface AccountUrl {
7 |
8 | String SERVICE_NAME = "ACCOUNT";
9 |
10 | String SERVICE_HOSTNAME = "http://ACCOUNT";
11 |
12 | String CHECK_ENOUGH_BALANCE = "/accounts/{userId}/enough";
13 |
14 | String ACCOUNT_BALANCE = "/accounts/{userId}/balance";
15 |
16 | String ACCOUNT_TRANSACTIONS = "/accounts/{userId}/transactions";
17 |
18 | static String buildUrl(String url) {
19 | return SERVICE_HOSTNAME + url;
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/account/api/src/main/java/com/akkafun/account/api/constants/AccountFlowType.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.api.constants;
2 |
3 | /**
4 | * Created by liubin on 2016/4/26.
5 | */
6 | public enum AccountFlowType {
7 |
8 | ORDER("下单");
9 |
10 | public String desc;
11 |
12 | AccountFlowType(String desc) {
13 | this.desc = desc;
14 | }
15 |
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/account/api/src/main/java/com/akkafun/account/api/events/AskReduceBalance.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.api.events;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.AskEvent;
5 | import com.akkafun.base.event.domain.Revokable;
6 | import com.fasterxml.jackson.annotation.JsonCreator;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | /**
10 | * Created by liubin on 2016/4/8.
11 | */
12 | public class AskReduceBalance extends AskEvent implements Revokable {
13 |
14 | public static final EventType EVENT_TYPE = EventType.ASK_REDUCE_BALANCE;
15 |
16 | @Override
17 | public EventType getType() {
18 | return EVENT_TYPE;
19 | }
20 |
21 | private Long userId;
22 |
23 | private Long balance;
24 |
25 | @JsonCreator
26 | public AskReduceBalance(
27 | @JsonProperty("userId") Long userId,
28 | @JsonProperty("balance") Long balance) {
29 | this.userId = userId;
30 | this.balance = balance;
31 | }
32 |
33 | public Long getUserId() {
34 | return userId;
35 | }
36 |
37 | public Long getBalance() {
38 | return balance;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "AskReduceBalance{" +
44 | "userId=" + userId +
45 | ", balance=" + balance +
46 | "} " + super.toString();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/account/core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | account-service-core
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | account-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 | com.akkafun.account.context.AccountApplication
17 |
18 |
19 |
20 |
21 |
22 | mysql
23 | mysql-connector-java
24 | runtime
25 |
26 |
27 |
28 | com.akkafun.mysteam
29 | common
30 | ${project.version}
31 |
32 |
33 |
34 | com.akkafun.mysteam
35 | common
36 | ${project.version}
37 | test-jar
38 | test
39 |
40 |
41 |
42 | com.akkafun.mysteam
43 | user-service-api
44 | ${project.version}
45 |
46 |
47 |
48 | com.akkafun.mysteam
49 | account-service-api
50 | ${project.version}
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-maven-plugin
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/context/AccountApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.context;
2 |
3 | import com.akkafun.common.event.config.EventConfiguration;
4 | import com.akkafun.common.scheduler.config.SchedulerConfiguration;
5 | import com.akkafun.common.spring.BaseConfiguration;
6 | import com.akkafun.common.spring.ServiceClientConfiguration;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.annotation.Import;
10 |
11 | /**
12 | * Created by liubin on 2016/3/28.
13 | */
14 | @SpringBootApplication
15 | @Import({BaseConfiguration.class, EventConfiguration.class, SchedulerConfiguration.class, ServiceClientConfiguration.class})
16 | public class AccountApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(AccountApplication.class, args);
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountFlowRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import com.akkafun.account.domain.AccountFlow;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public interface AccountFlowRepository extends PagingAndSortingRepository, AccountFlowRepositoryCustom {
10 | }
11 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountFlowRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/4/26.
7 | */
8 | public interface AccountFlowRepositoryCustom extends AbstractRepository {
9 | }
10 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountFlowRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public class AccountFlowRepositoryImpl implements AccountFlowRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 |
15 | @Override
16 | public EntityManager getEm() {
17 | return em;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import com.akkafun.account.domain.Account;
4 | import org.springframework.data.jpa.repository.Query;
5 | import org.springframework.data.repository.PagingAndSortingRepository;
6 |
7 | /**
8 | * Created by liubin on 2016/4/26.
9 | */
10 | public interface AccountRepository extends PagingAndSortingRepository, AccountRepositoryCustom {
11 |
12 | Account findByUserId(Long userId);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/4/26.
7 | */
8 | public interface AccountRepositoryCustom extends AbstractRepository {
9 | }
10 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/dao/AccountRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public class AccountRepositoryImpl implements AccountRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 |
15 | @Override
16 | public EntityManager getEm() {
17 | return em;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/domain/Account.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.domain;
2 |
3 | import com.akkafun.common.domain.VersionEntity;
4 |
5 | import javax.persistence.*;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @Entity
11 | @Table(name = "account")
12 | public class Account extends VersionEntity {
13 |
14 | @Id
15 | @GeneratedValue(strategy = GenerationType.AUTO)
16 | private Long id;
17 |
18 | @Column
19 | private Long balance;
20 |
21 | @Column
22 | private Long userId;
23 |
24 | public Long getId() {
25 | return id;
26 | }
27 |
28 | public void setId(Long id) {
29 | this.id = id;
30 | }
31 |
32 | public Long getBalance() {
33 | return balance;
34 | }
35 |
36 | public void setBalance(Long balance) {
37 | this.balance = balance;
38 | }
39 |
40 | public Long getUserId() {
41 | return userId;
42 | }
43 |
44 | public void setUserId(Long userId) {
45 | this.userId = userId;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/domain/AccountFlow.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.domain;
2 |
3 | import com.akkafun.account.api.constants.AccountFlowType;
4 | import com.akkafun.common.domain.AuditEntity;
5 | import com.akkafun.common.domain.VersionEntity;
6 |
7 | import javax.persistence.*;
8 |
9 | /**
10 | * Created by liubin on 2016/3/28.
11 | */
12 | @Entity
13 | @Table(name = "account_flow")
14 | public class AccountFlow extends AuditEntity {
15 |
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.AUTO)
18 | private Long id;
19 |
20 | @Column
21 | private Long balance;
22 |
23 | @Column
24 | private Long accountId;
25 |
26 | @Column
27 | private String description;
28 |
29 | @Column
30 | @Enumerated(EnumType.STRING)
31 | private AccountFlowType type;
32 |
33 | public Long getId() {
34 | return id;
35 | }
36 |
37 | public void setId(Long id) {
38 | this.id = id;
39 | }
40 |
41 | public Long getBalance() {
42 | return balance;
43 | }
44 |
45 | public void setBalance(Long balance) {
46 | this.balance = balance;
47 | }
48 |
49 | public Long getAccountId() {
50 | return accountId;
51 | }
52 |
53 | public void setAccountId(Long accountId) {
54 | this.accountId = accountId;
55 | }
56 |
57 | public String getDescription() {
58 | return description;
59 | }
60 |
61 | public void setDescription(String description) {
62 | this.description = description;
63 | }
64 |
65 | public AccountFlowType getType() {
66 | return type;
67 | }
68 |
69 | public void setType(AccountFlowType type) {
70 | this.type = type;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/handler/AskReduceBalanceHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.handler;
2 |
3 | import com.akkafun.account.api.events.AskReduceBalance;
4 | import com.akkafun.account.service.AccountService;
5 | import com.akkafun.base.api.BooleanWrapper;
6 | import com.akkafun.base.event.constants.FailureInfo;
7 | import com.akkafun.base.exception.AppBusinessException;
8 | import com.akkafun.common.event.handler.RevokableAskEventHandler;
9 | import com.akkafun.common.spring.ApplicationContextHolder;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 |
13 | /**
14 | * Created by liubin on 2016/6/24.
15 | */
16 | public class AskReduceBalanceHandler implements RevokableAskEventHandler {
17 |
18 | private static Logger logger = LoggerFactory.getLogger(AskReduceBalanceHandler.class);
19 |
20 | @Override
21 | public void processRevoke(AskReduceBalance originEvent, FailureInfo failureInfo) {
22 | logger.debug("AskReduceBalanceHandler processRevoke, receive AskReduceBalance: " + originEvent);
23 |
24 | AccountService accountService = ApplicationContextHolder.context.getBean(AccountService.class);
25 | accountService.addBalance(originEvent.getUserId(), originEvent.getBalance());
26 | }
27 |
28 | @Override
29 | public BooleanWrapper processRequest(AskReduceBalance event) {
30 | logger.debug("AskReduceBalanceHandler processRequest, receive AskReduceBalance: " + event);
31 |
32 | if(event.getUserId() == null || event.getBalance() == null) {
33 | return new BooleanWrapper(false, "userId or balance is null");
34 | }
35 |
36 | AccountService accountService = ApplicationContextHolder.context.getBean(AccountService.class);
37 | accountService.reduceBalance(event.getUserId(), event.getBalance());
38 | return new BooleanWrapper(true);
39 | }
40 |
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/handler/UserCreatedHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.handler;
2 |
3 | import com.akkafun.account.service.AccountService;
4 | import com.akkafun.common.event.handler.NotifyEventHandler;
5 | import com.akkafun.common.spring.ApplicationContextHolder;
6 | import com.akkafun.user.api.events.UserCreated;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.dao.DataIntegrityViolationException;
10 |
11 | /**
12 | * Created by liubin on 2016/4/14.
13 | */
14 | public class UserCreatedHandler implements NotifyEventHandler {
15 |
16 | protected Logger logger = LoggerFactory.getLogger(UserCreatedHandler.class);
17 |
18 | @Override
19 | public void notify(UserCreated event) {
20 |
21 | AccountService accountService = ApplicationContextHolder.context.getBean(AccountService.class);
22 |
23 | try {
24 | accountService.initAccount(event.getUserId());
25 | } catch (DataIntegrityViolationException e) {
26 | logger.warn(String.format("userId=%d的account在数据库已存在, errorMsg: %s",
27 | event.getUserId(), e.getMessage()));
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/account/core/src/main/java/com/akkafun/account/web/AccountController.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account.web;
2 |
3 | import com.akkafun.account.domain.Account;
4 | import com.akkafun.account.service.AccountService;
5 | import com.akkafun.base.api.BooleanWrapper;
6 | import com.akkafun.base.api.CommonErrorCode;
7 | import com.akkafun.base.exception.AppBusinessException;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.web.bind.annotation.*;
11 |
12 | import static com.akkafun.account.api.AccountUrl.ACCOUNT_BALANCE;
13 | import static com.akkafun.account.api.AccountUrl.ACCOUNT_TRANSACTIONS;
14 | import static com.akkafun.account.api.AccountUrl.CHECK_ENOUGH_BALANCE;
15 |
16 | /**
17 | * Created by liubin on 2016/3/29.
18 | */
19 | @RestController
20 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
21 | public class AccountController {
22 |
23 | @Autowired
24 | AccountService accountService;
25 |
26 | @RequestMapping(value = CHECK_ENOUGH_BALANCE, method = RequestMethod.GET)
27 | public BooleanWrapper checkAccountBalanceEnough(@PathVariable("userId") Long userId,
28 | @RequestParam("balance") Long balance) {
29 | boolean result = accountService.checkEnoughBalance(userId, balance);
30 | return new BooleanWrapper(result);
31 | }
32 |
33 | @RequestMapping(value = ACCOUNT_BALANCE, method = RequestMethod.GET)
34 | public Long accountBalance(@PathVariable(value = "userId") Long userId) {
35 |
36 | return accountService.getByUserId(userId).getBalance();
37 | }
38 |
39 | @RequestMapping(value = ACCOUNT_TRANSACTIONS, method = RequestMethod.POST)
40 | public Long operateAccountBalance(
41 | @PathVariable(value = "userId") Long userId,
42 | @RequestParam(value = "amount") Long amount) {
43 |
44 | if(amount >= 0L) {
45 | return accountService.addBalance(userId, amount);
46 | } else {
47 | return accountService.reduceBalance(userId, Math.abs(amount));
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/account/core/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: account
4 | cloud:
5 | config:
6 | uri: ${CONFIG_SERVER_URI:http://localhost:8888}
7 | failFast: true
8 | encrypt:
9 | failOnError: true
10 |
--------------------------------------------------------------------------------
/account/core/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/account-service.log
15 |
16 |
17 | logs/account-service-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/account/core/src/test/java/com/akkafun/account/TestClass.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.account;
2 |
3 | /**
4 | * Created by liubin on 2016/5/6.
5 | */
6 | public class TestClass{
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/account/docs/account-service.sql:
--------------------------------------------------------------------------------
1 | /*==============================================================*/
2 | /* DBMS name: MySQL 5.0 */
3 | /* Created on: 2016/4/26 9:54:25 */
4 | /*==============================================================*/
5 |
6 |
7 | drop table if exists account;
8 |
9 | drop table if exists account_flow;
10 |
11 | /*==============================================================*/
12 | /* Table: account */
13 | /*==============================================================*/
14 | create table account
15 | (
16 | id bigint unsigned not null auto_increment,
17 | balance bigint not null,
18 | userId bigint not null,
19 | optlock int default 0,
20 | createTime datetime,
21 | updateTime datetime,
22 | primary key (id)
23 | );
24 |
25 | /*==============================================================*/
26 | /* Table: account_flow */
27 | /*==============================================================*/
28 | create table account_flow
29 | (
30 | id bigint unsigned not null auto_increment,
31 | balance bigint not null,
32 | accountId bigint not null,
33 | description varchar(255),
34 | type varchar(32),
35 | createTime datetime,
36 | updateTime datetime,
37 | primary key (id)
38 | );
39 |
40 |
--------------------------------------------------------------------------------
/account/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | account-service
6 |
7 | api
8 | core
9 |
10 | pom
11 |
12 |
13 | com.akkafun.mysteam
14 | base
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/apiutils/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | apiutils
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | base
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 | org.hibernate
18 | hibernate-validator
19 |
20 |
21 |
22 | com.fasterxml.jackson.core
23 | jackson-annotations
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/Constants.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base;
2 |
3 | /**
4 | * Created by liubin on 2016/6/15.
5 | */
6 | public interface Constants {
7 |
8 | int ASK_TIMEOUT = 30000;
9 |
10 | int MAX_BATCH_QUERY_SIZE = 100;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/api/BooleanWrapper.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.api;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 |
6 | /**
7 | * Created by liubin on 2016/5/6.
8 | */
9 | public class BooleanWrapper {
10 |
11 | private boolean success;
12 |
13 | private String message;
14 |
15 | public BooleanWrapper(boolean success) {
16 | this(success, null);
17 | }
18 |
19 | @JsonCreator
20 | public BooleanWrapper(
21 | @JsonProperty("success") boolean success,
22 | @JsonProperty("message") String message) {
23 | this.success = success;
24 | this.message = message;
25 | }
26 |
27 | public boolean isSuccess() {
28 | return success;
29 | }
30 |
31 | public String getMessage() {
32 | return message;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/api/CommonErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/3.
5 | */
6 | public enum CommonErrorCode implements ErrorCode {
7 |
8 | BAD_REQUEST(400, "请求的参数个数或格式不符合要求"),
9 | INVALID_ARGUMENT(400, "请求的参数不正确"),
10 | UNAUTHORIZED(401, "无权访问"),
11 | FORBIDDEN(403, "禁止访问"),
12 | NOT_FOUND(404, "请求的地址不正确"),
13 | METHOD_NOT_ALLOWED(405, "不允许的请求方法"),
14 | NOT_ACCEPTABLE(406, "不接受的请求"),
15 | CONFLICT(409, "资源冲突"),
16 | UNSUPPORTED_MEDIA_TYPE(415, "不支持的Media Type"),
17 | INTERNAL_ERROR(500, "服务器内部错误"),
18 | SERVICE_UNAVAILABLE(503, "服务不可用"),
19 | GATEWAY_TIMEOUT(504, "请求服务超时");
20 |
21 | private int status;
22 |
23 | private String message;
24 |
25 | CommonErrorCode(int status, String message) {
26 | this.status = status;
27 | this.message = message;
28 | }
29 |
30 | public static CommonErrorCode fromHttpStatus(int httpStatus) {
31 | for(CommonErrorCode errorCode : values()) {
32 | if(errorCode.getStatus() == httpStatus) {
33 | return errorCode;
34 | }
35 | }
36 | return INTERNAL_ERROR;
37 | }
38 |
39 |
40 | @Override
41 | public String getCode() {
42 | return this.name();
43 | }
44 |
45 | @Override
46 | public int getStatus() {
47 | return status;
48 | }
49 |
50 | @Override
51 | public String getMessage() {
52 | return message;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/api/Error.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.api;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 |
6 | /**
7 | * Created by liubin on 15-8-3.
8 | */
9 | public class Error {
10 |
11 | private String code;
12 |
13 | private String message;
14 |
15 | private String requestUri;
16 |
17 | @JsonCreator
18 | public Error(@JsonProperty("code") String code,
19 | @JsonProperty("requestUri") String requestUri,
20 | @JsonProperty(value = "message", defaultValue = "") String message) {
21 | this.code = code;
22 | this.requestUri = requestUri;
23 | this.message = message;
24 | }
25 |
26 | public String getCode() {
27 | return code;
28 | }
29 |
30 | public String getMessage() {
31 | return message;
32 | }
33 |
34 | public String getRequestUri() {
35 | return requestUri;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "Error{" +
41 | "code='" + code + '\'' +
42 | ", message='" + message + '\'' +
43 | ", requestUri='" + requestUri + '\'' +
44 | '}';
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/api/ErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/3.
5 | */
6 | public interface ErrorCode {
7 |
8 | String getCode();
9 |
10 | int getStatus();
11 |
12 | String getMessage();
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/constants/EventType.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.constants;
2 |
3 | /**
4 | * Created by liubin on 2016/4/13.
5 | */
6 | public enum EventType {
7 |
8 | ASK_RESPONSE,
9 |
10 | REVOKE_ASK,
11 |
12 |
13 | //user service
14 | USER_CREATED,
15 |
16 | //order service
17 | ORDER_CREATE_PENDING,
18 |
19 | //account service
20 | ASK_REDUCE_BALANCE,
21 |
22 | //coupon service
23 | ASK_USE_COUPON,
24 |
25 |
26 | NOTIFY_FIRST_TEST_EVENT,
27 |
28 | NOTIFY_SECOND_TEST_EVENT,
29 |
30 | ASK_TEST_EVENT,
31 |
32 | REVOKABLE_ASK_TEST_EVENT;
33 |
34 |
35 | public static EventType valueOfIgnoreCase(String name) {
36 | if(name == null) return null;
37 | return valueOf(name.toUpperCase());
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/constants/FailureInfo.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.constants;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | /**
9 | * Created by liubin on 2016/6/3.
10 | */
11 | public class FailureInfo {
12 |
13 | private FailureReason reason;
14 |
15 | private LocalDateTime failureTime;
16 |
17 | private String message;
18 |
19 | public FailureInfo(FailureReason reason, LocalDateTime failureTime) {
20 | this(reason, failureTime, null);
21 | }
22 |
23 | @JsonCreator
24 | public FailureInfo(
25 | @JsonProperty("reason") FailureReason reason,
26 | @JsonProperty("failureTime") LocalDateTime failureTime,
27 | @JsonProperty("message") String message) {
28 | this.reason = reason;
29 | this.failureTime = failureTime;
30 | this.message = message;
31 | }
32 |
33 | public FailureReason getReason() {
34 | return reason;
35 | }
36 |
37 | public void setReason(FailureReason reason) {
38 | this.reason = reason;
39 | }
40 |
41 | public LocalDateTime getFailureTime() {
42 | return failureTime;
43 | }
44 |
45 | public void setFailureTime(LocalDateTime failureTime) {
46 | this.failureTime = failureTime;
47 | }
48 |
49 | public String getMessage() {
50 | return message;
51 | }
52 |
53 | public void setMessage(String message) {
54 | this.message = message;
55 | }
56 |
57 | @Override
58 | public String toString() {
59 | return "FailureInfo{" +
60 | "reason=" + reason +
61 | ", failureTime=" + failureTime +
62 | ", message='" + message + '\'' +
63 | '}';
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/constants/FailureReason.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.constants;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public enum FailureReason {
7 |
8 | TIMEOUT("事件超时"),
9 |
10 | FAILED("事件失败"),
11 |
12 | CANCELLED("事件取消");
13 |
14 | public String desc;
15 |
16 | FailureReason(String desc) {
17 | this.desc = desc;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/AskEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public abstract class AskEvent extends BaseEvent {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/AskResponseEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 |
6 | /**
7 | * Created by liubin on 2016/6/3.
8 | */
9 | public final class AskResponseEvent extends BaseEvent {
10 |
11 | public static final EventType EVENT_TYPE = EventType.ASK_RESPONSE;
12 |
13 | @Override
14 | public EventType getType() {
15 | return EVENT_TYPE;
16 | }
17 |
18 | private boolean success;
19 |
20 | private String message;
21 |
22 | private Long askEventId;
23 |
24 | public AskResponseEvent(
25 | @JsonProperty("success") boolean success,
26 | @JsonProperty("message") String message,
27 | @JsonProperty("askEventId") Long askEventId) {
28 | this.success = success;
29 | this.message = message;
30 | this.askEventId = askEventId;
31 | }
32 |
33 | public boolean isSuccess() {
34 | return success;
35 | }
36 |
37 | public Long getAskEventId() {
38 | return askEventId;
39 | }
40 |
41 | public String getMessage() {
42 | return message;
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return "AskResponseEvent{" +
48 | "success=" + success +
49 | "message=" + message +
50 | ", askEventId=" + askEventId +
51 | "} " + super.toString();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/BaseEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 |
4 | import com.akkafun.base.event.constants.EventType;
5 | import com.sun.javafx.event.EventUtil;
6 |
7 | import java.time.LocalDateTime;
8 | import java.util.Objects;
9 | import java.util.UUID;
10 |
11 | /**
12 | * 子类必须定义static变量EVENT_TYPE
13 | * 例如: public static final EventType EVENT_TYPE = EventType.TEST_EVENT;
14 | * Created by liubin on 2016/4/8.
15 | */
16 | public abstract class BaseEvent {
17 |
18 | protected Long id;
19 |
20 | protected LocalDateTime createTime;
21 |
22 | public BaseEvent() {
23 | createTime = LocalDateTime.now();
24 | }
25 |
26 | public void setId(Long id) {
27 | this.id = id;
28 | }
29 |
30 | public Long getId() {
31 | return id;
32 | }
33 |
34 | public LocalDateTime getCreateTime() {
35 | return createTime;
36 | }
37 |
38 | public abstract EventType getType();
39 |
40 |
41 |
42 | @Override
43 | public boolean equals(Object o) {
44 | if (this == o) return true;
45 | if (!(o instanceof BaseEvent)) return false;
46 | BaseEvent baseEvent = (BaseEvent) o;
47 | return Objects.equals(id, baseEvent.id);
48 | }
49 |
50 | @Override
51 | public int hashCode() {
52 | return Objects.hash(id);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/NotifyEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public abstract class NotifyEvent extends BaseEvent {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/Revokable.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public interface Revokable {
7 | }
8 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/event/domain/RevokeAskEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.event.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.constants.FailureInfo;
5 | import com.akkafun.base.event.constants.FailureReason;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 |
8 | /**
9 | * Created by liubin on 2016/6/3.
10 | */
11 | public final class RevokeAskEvent extends BaseEvent {
12 |
13 | public static final EventType EVENT_TYPE = EventType.REVOKE_ASK;
14 |
15 | @Override
16 | public EventType getType() {
17 | return EVENT_TYPE;
18 | }
19 |
20 | private FailureInfo failureInfo;
21 |
22 | private Long askEventId;
23 |
24 | public RevokeAskEvent(
25 | @JsonProperty("failureInfo") FailureInfo failureInfo,
26 | @JsonProperty("askEventId") Long askEventId) {
27 | this.failureInfo = failureInfo;
28 | this.askEventId = askEventId;
29 | }
30 |
31 | public FailureInfo getFailureInfo() {
32 | return failureInfo;
33 | }
34 |
35 | public Long getAskEventId() {
36 | return askEventId;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return "RevokeAskEvent{" +
42 | "failureInfo=" + failureInfo +
43 | ", askEventId=" + askEventId +
44 | "} " + super.toString();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/exception/AppBusinessException.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.exception;
2 |
3 | import com.akkafun.base.api.CommonErrorCode;
4 | import com.akkafun.base.api.ErrorCode;
5 |
6 | /**
7 | * Created by liubin on 2016/5/3.
8 | */
9 | public class AppBusinessException extends BaseException {
10 |
11 | private static final ErrorCode DEFAULT_CODE = CommonErrorCode.INTERNAL_ERROR;
12 |
13 | private String code = DEFAULT_CODE.getCode();
14 |
15 | //类似Http状态码
16 | private int httpStatus = DEFAULT_CODE.getStatus();
17 |
18 | public AppBusinessException(String code, int httpStatus, String message) {
19 | super(message);
20 | this.code = code;
21 | this.httpStatus = httpStatus;
22 | }
23 |
24 | public AppBusinessException(String message) {
25 | super(message);
26 | }
27 |
28 | /**
29 | * @param errorCode 状态码, 这个字段会在错误信息里返回给客户端.
30 | * @param message
31 | */
32 | public AppBusinessException(ErrorCode errorCode, String message) {
33 | this(errorCode.getCode(), errorCode.getStatus(), message);
34 | }
35 |
36 | public AppBusinessException(ErrorCode errorCode) {
37 | this(errorCode, errorCode.getMessage());
38 | }
39 |
40 | public String getCode() {
41 | return code;
42 | }
43 |
44 | public int getHttpStatus() {
45 | return httpStatus;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/exception/BaseException.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.exception;
2 |
3 | /**
4 | * Created by liubin on 2016/4/14.
5 | */
6 | public class BaseException extends RuntimeException {
7 |
8 | public BaseException(String message) {
9 | super(message);
10 | }
11 |
12 | public BaseException(String message, Throwable cause) {
13 | super(message, cause);
14 | }
15 |
16 | public BaseException(Throwable cause) {
17 | super(cause);
18 | }
19 |
20 | protected BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
21 | super(message, cause, enableSuppression, writableStackTrace);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/exception/RemoteCallException.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.exception;
2 |
3 | import com.akkafun.base.api.Error;
4 |
5 | /**
6 | * hystrix会忽略这个异常, 不会触发熔断
7 | * Created by liubin on 2016/5/3.
8 | */
9 | public class RemoteCallException extends AppBusinessException {
10 |
11 | private Error originError;
12 |
13 | public RemoteCallException(Error error, int httpStatus) {
14 | super(error.getCode(), httpStatus, "调用远程服务异常, cause: " + error.getMessage());
15 | this.originError = error;
16 | }
17 |
18 | public Error getOriginError() {
19 | return originError;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apiutils/src/main/java/com/akkafun/base/exception/ServiceUnavailableException.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.base.exception;
2 |
3 | import com.akkafun.base.api.CommonErrorCode;
4 | import com.akkafun.base.api.ErrorCode;
5 |
6 | /**
7 | * Created by liubin on 2016/5/3.
8 | */
9 | public class ServiceUnavailableException extends AppBusinessException {
10 |
11 | private static final ErrorCode ERROR_CODE = CommonErrorCode.SERVICE_UNAVAILABLE;
12 |
13 | public ServiceUnavailableException(String message) {
14 | super(ERROR_CODE.getCode(), ERROR_CODE.getStatus(), " 远程服务不可用: " + message);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/domain/AuditEntity.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.domain;
2 |
3 | import org.springframework.data.annotation.CreatedDate;
4 | import org.springframework.data.annotation.LastModifiedDate;
5 | import org.springframework.data.jpa.domain.support.AuditingEntityListener;
6 |
7 | import javax.persistence.Column;
8 | import javax.persistence.EntityListeners;
9 | import javax.persistence.MappedSuperclass;
10 | import java.time.LocalDateTime;
11 |
12 | /**
13 | * Created by liubin on 2016/3/28.
14 | */
15 | @MappedSuperclass
16 | @EntityListeners(AuditingEntityListener.class)
17 | public abstract class AuditEntity {
18 |
19 | @CreatedDate
20 | @Column
21 | private LocalDateTime createTime;
22 |
23 | @LastModifiedDate
24 | @Column
25 | private LocalDateTime updateTime;
26 |
27 | public LocalDateTime getCreateTime() {
28 | return createTime;
29 | }
30 |
31 | public void setCreateTime(LocalDateTime createTime) {
32 | this.createTime = createTime;
33 | }
34 |
35 | public LocalDateTime getUpdateTime() {
36 | return updateTime;
37 | }
38 |
39 | public void setUpdateTime(LocalDateTime updateTime) {
40 | this.updateTime = updateTime;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/domain/LockableEntity.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.domain;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.MappedSuperclass;
5 | import javax.persistence.Version;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @MappedSuperclass
11 | public abstract class LockableEntity {
12 |
13 | @Version
14 | @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
15 | private long version;
16 |
17 | public long getVersion() {
18 | return version;
19 | }
20 |
21 | public void setVersion(long version) {
22 | this.version = version;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/domain/VersionEntity.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.domain;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.MappedSuperclass;
5 | import javax.persistence.Version;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @MappedSuperclass
11 | public abstract class VersionEntity extends AuditEntity {
12 |
13 | @Version
14 | @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false)
15 | private long version;
16 |
17 | public long getVersion() {
18 | return version;
19 | }
20 |
21 | public void setVersion(long version) {
22 | this.version = version;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/AskParameter.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event;
2 |
3 | import com.akkafun.base.event.domain.AskEvent;
4 |
5 | import java.time.LocalDateTime;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.Optional;
9 |
10 | /**
11 | * Created by liubin on 2016/6/6.
12 | */
13 | public class AskParameter {
14 |
15 | private boolean united;
16 |
17 | private List extends AskEvent> askEvents;
18 |
19 | private Class> callbackClass;
20 |
21 | private Map extraParams;
22 |
23 | private Optional timeoutTime;
24 |
25 | protected AskParameter(boolean united, List extends AskEvent> askEvents,
26 | Class> callbackClass, Map extraParams, Optional timeoutTime) {
27 | this.united = united;
28 | this.askEvents = askEvents;
29 | this.callbackClass = callbackClass;
30 | this.extraParams = extraParams;
31 | this.timeoutTime = timeoutTime;
32 | }
33 |
34 | public boolean isUnited() {
35 | return united;
36 | }
37 |
38 | public List extends AskEvent> getAskEvents() {
39 | return askEvents;
40 | }
41 |
42 | public Class> getCallbackClass() {
43 | return callbackClass;
44 | }
45 |
46 | public Map getExtraParams() {
47 | return extraParams;
48 | }
49 |
50 | public Optional getTimeoutTime() {
51 | return timeoutTime;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/config/InitBindProducer.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.config;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.AskResponseEvent;
5 | import com.akkafun.base.event.domain.RevokeAskEvent;
6 | import com.akkafun.common.event.EventRegistry;
7 | import org.springframework.beans.factory.InitializingBean;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.cloud.stream.binding.BinderAwareChannelResolver;
10 |
11 | import java.util.HashSet;
12 | import java.util.Set;
13 |
14 | /**
15 | * Created by liubin on 2016/6/28.
16 | */
17 | public class InitBindProducer implements InitializingBean {
18 |
19 | @Autowired
20 | private BinderAwareChannelResolver binderAwareChannelResolver;
21 |
22 | private Set preInitializeProducers = new HashSet<>();
23 |
24 | public InitBindProducer() {
25 | preInitializeProducers.add(AskResponseEvent.EVENT_TYPE);
26 | preInitializeProducers.add(RevokeAskEvent.EVENT_TYPE);
27 | }
28 |
29 | @Override
30 | public void afterPropertiesSet() throws Exception {
31 | preInitializeProducers.stream().forEach(x -> binderAwareChannelResolver.resolveDestination(x.name()));
32 | }
33 |
34 | public void addPreInitializeProducers(EventType eventType) {
35 | preInitializeProducers.add(eventType);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/constant/AskEventStatus.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.constant;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public enum AskEventStatus {
7 |
8 | PENDING("请求中"),
9 |
10 | TIMEOUT("已超时"),
11 |
12 | FAILED("已失败"),
13 |
14 | SUCCESS("完成"),
15 |
16 | CANCELLED("已取消");
17 |
18 | public String desc;
19 |
20 | AskEventStatus(String desc) {
21 | this.desc = desc;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/constant/EventCategory.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.constant;
2 |
3 | /**
4 | * Created by liubin on 2016/6/3.
5 | */
6 | public enum EventCategory {
7 |
8 | NOTIFY("通知事件"),
9 |
10 | ASK("请求事件"),
11 |
12 | REVOKE("撤销事件"),
13 |
14 | ASKRESP("响应事件");
15 |
16 | public String desc;
17 |
18 | EventCategory(String desc) {
19 | this.desc = desc;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/constant/ProcessStatus.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.constant;
2 |
3 | /**
4 | * Created by liubin on 2016/4/8.
5 | */
6 | public enum ProcessStatus {
7 |
8 | NEW("未处理"),
9 |
10 | PROCESSED("已处理"),
11 |
12 | IGNORE("忽略");
13 |
14 | public String desc;
15 |
16 | ProcessStatus(String desc) {
17 | this.desc = desc;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskRequestEventPublishRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.domain.AskRequestEventPublish;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface AskRequestEventPublishRepository extends
9 | EventPublishRepository, AskRequestEventPublishRepositoryCustom {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskRequestEventPublishRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface AskRequestEventPublishRepositoryCustom extends AbstractRepository{
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskRequestEventPublishRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public class AskRequestEventPublishRepositoryImpl implements AskRequestEventPublishRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 | @Override
15 | public EntityManager getEm() {
16 | return em;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskResponseEventPublishRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.domain.AskResponseEventPublish;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface AskResponseEventPublishRepository extends
9 | EventPublishRepository, AskResponseEventPublishRepositoryCustom {
10 |
11 | Long countByAskEventId(Long askEventId);
12 |
13 | AskResponseEventPublish getByAskEventId(Long askEventId);
14 | }
15 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskResponseEventPublishRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface AskResponseEventPublishRepositoryCustom extends AbstractRepository{
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/AskResponseEventPublishRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public class AskResponseEventPublishRepositoryImpl implements AskResponseEventPublishRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 | @Override
15 | public EntityManager getEm() {
16 | return em;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventProcessRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.ProcessStatus;
4 | import com.akkafun.common.event.domain.EventProcess;
5 | import org.springframework.data.repository.PagingAndSortingRepository;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by liubin on 2016/3/29.
11 | */
12 | public interface EventProcessRepository extends PagingAndSortingRepository, EventProcessRepositoryCustom{
13 |
14 | List findByStatus(ProcessStatus status);
15 |
16 | EventProcess getByEventId(Long eventId);
17 |
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventProcessRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface EventProcessRepositoryCustom extends AbstractRepository{
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventProcessRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.ProcessStatus;
4 |
5 | import javax.persistence.EntityManager;
6 | import javax.persistence.PersistenceContext;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | /**
11 | * Created by liubin on 2016/3/29.
12 | */
13 | public class EventProcessRepositoryImpl implements EventProcessRepositoryCustom {
14 |
15 | @PersistenceContext
16 | private EntityManager em;
17 |
18 | @Override
19 | public EntityManager getEm() {
20 | return em;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventPublishRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.ProcessStatus;
4 | import com.akkafun.common.event.domain.EventPublish;
5 | import org.springframework.data.repository.NoRepositoryBean;
6 | import org.springframework.data.repository.PagingAndSortingRepository;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Created by liubin on 2016/3/29.
12 | */
13 | @NoRepositoryBean
14 | public interface EventPublishRepository extends PagingAndSortingRepository{
15 |
16 | List findByStatus(ProcessStatus status);
17 |
18 | T getByEventId(Long eventId);
19 |
20 | List findByEventIdIn(List eventIds);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchProcessRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.ProcessStatus;
4 | import com.akkafun.common.event.domain.EventWatchProcess;
5 | import org.springframework.data.repository.PagingAndSortingRepository;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Created by liubin on 2016/3/29.
11 | */
12 | public interface EventWatchProcessRepository extends PagingAndSortingRepository,
13 | EventWatchProcessRepositoryCustom{
14 |
15 | List findByStatus(ProcessStatus status);
16 | }
17 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchProcessRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 | import com.akkafun.common.event.constant.ProcessStatus;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public interface EventWatchProcessRepositoryCustom extends AbstractRepository{
10 |
11 | int updateStatusBatch(Long[] ids, ProcessStatus status);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchProcessRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.ProcessStatus;
4 | import com.akkafun.common.utils.SQLUtils;
5 |
6 | import javax.persistence.EntityManager;
7 | import javax.persistence.PersistenceContext;
8 | import java.time.LocalDateTime;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | /**
13 | * Created by liubin on 2016/3/29.
14 | */
15 | public class EventWatchProcessRepositoryImpl implements EventWatchProcessRepositoryCustom {
16 |
17 | @PersistenceContext
18 | private EntityManager em;
19 |
20 | @Override
21 | public EntityManager getEm() {
22 | return em;
23 | }
24 |
25 |
26 | @Override
27 | public int updateStatusBatch(Long[] ids, ProcessStatus status) {
28 |
29 | return SQLUtils.updateByIdBatch(ids, (updateIds) -> {
30 | StringBuilder sql = new StringBuilder(
31 | String.format("update event_watch_process set status ='%s' where id in (", status.toString()));
32 | for (Long id : updateIds) {
33 | sql.append(id).append(",");
34 | }
35 | sql.replace(sql.length()-1, sql.length(), ")");
36 | return getEm().createNativeQuery(sql.toString()).executeUpdate();
37 | });
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.constant.AskEventStatus;
4 | import com.akkafun.common.event.domain.EventWatch;
5 | import org.springframework.data.repository.PagingAndSortingRepository;
6 |
7 | import java.time.LocalDateTime;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by liubin on 2016/3/29.
12 | */
13 | public interface EventWatchRepository extends PagingAndSortingRepository, EventWatchRepositoryCustom{
14 |
15 |
16 | List findByAskEventStatusAndTimeoutTimeBefore(AskEventStatus askEventStatus, LocalDateTime timeoutTime);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/6/6.
7 | */
8 | public interface EventWatchRepositoryCustom extends AbstractRepository {
9 | }
10 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/EventWatchRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public class EventWatchRepositoryImpl implements EventWatchRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 | @Override
15 | public EntityManager getEm() {
16 | return em;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/NotifyEventPublishRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.domain.NotifyEventPublish;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface NotifyEventPublishRepository extends
9 | EventPublishRepository, NotifyEventPublishRepositoryCustom {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/NotifyEventPublishRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface NotifyEventPublishRepositoryCustom extends AbstractRepository{
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/NotifyEventPublishRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public class NotifyEventPublishRepositoryImpl implements NotifyEventPublishRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 | @Override
15 | public EntityManager getEm() {
16 | return em;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/RevokeAskEventPublishRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.event.domain.RevokeAskEventPublish;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface RevokeAskEventPublishRepository extends
9 | EventPublishRepository, RevokeAskEventPublishRepositoryCustom {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/RevokeAskEventPublishRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/3/29.
7 | */
8 | public interface RevokeAskEventPublishRepositoryCustom extends AbstractRepository{
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/dao/RevokeAskEventPublishRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public class RevokeAskEventPublishRepositoryImpl implements RevokeAskEventPublishRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 | @Override
15 | public EntityManager getEm() {
16 | return em;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/AskRequestEventPublish.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import com.akkafun.common.event.constant.AskEventStatus;
4 |
5 | import javax.persistence.*;
6 | import java.time.LocalDateTime;
7 |
8 | /**
9 | * Created by liubin on 2016/3/28.
10 | */
11 | @Entity
12 | @DiscriminatorValue("ASK")
13 | public class AskRequestEventPublish extends EventPublish {
14 |
15 | @Column
16 | @Enumerated(EnumType.STRING)
17 | private AskEventStatus askEventStatus;
18 |
19 | @Column
20 | private Long watchId;
21 |
22 | public AskEventStatus getAskEventStatus() {
23 | return askEventStatus;
24 | }
25 |
26 | public void setAskEventStatus(AskEventStatus askEventStatus) {
27 | this.askEventStatus = askEventStatus;
28 | }
29 |
30 | public Long getWatchId() {
31 | return watchId;
32 | }
33 |
34 | public void setWatchId(Long watchId) {
35 | this.watchId = watchId;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/AskResponseEventPublish.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.DiscriminatorValue;
5 | import javax.persistence.Entity;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @Entity
11 | @DiscriminatorValue("ASKRESP")
12 | public class AskResponseEventPublish extends EventPublish {
13 |
14 | @Column
15 | private boolean success;
16 |
17 | @Column
18 | private Long askEventId;
19 |
20 | public boolean isSuccess() {
21 | return success;
22 | }
23 |
24 | public void setSuccess(boolean success) {
25 | this.success = success;
26 | }
27 |
28 | public Long getAskEventId() {
29 | return askEventId;
30 | }
31 |
32 | public void setAskEventId(Long askEventId) {
33 | this.askEventId = askEventId;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/EventPublish.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.common.domain.VersionEntity;
5 | import com.akkafun.common.event.constant.ProcessStatus;
6 |
7 | import javax.persistence.*;
8 |
9 | /**
10 | * Created by liubin on 2016/3/28.
11 | */
12 | @Entity
13 | @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
14 | @DiscriminatorColumn(name="eventCategory")
15 | @Table(name = "event_publish")
16 | public abstract class EventPublish extends VersionEntity {
17 |
18 | @Id
19 | @GeneratedValue(strategy = GenerationType.AUTO)
20 | private Long id;
21 |
22 | @Column
23 | private String payload;
24 |
25 | @Column
26 | @Enumerated(EnumType.STRING)
27 | private ProcessStatus status = ProcessStatus.NEW;
28 |
29 | @Column(unique = true)
30 | private Long eventId;
31 |
32 | @Column
33 | @Enumerated(EnumType.STRING)
34 | private EventType eventType;
35 |
36 |
37 | public Long getId() {
38 | return id;
39 | }
40 |
41 | public void setId(Long id) {
42 | this.id = id;
43 | }
44 |
45 | public String getPayload() {
46 | return payload;
47 | }
48 |
49 | public void setPayload(String payload) {
50 | this.payload = payload;
51 | }
52 |
53 | public ProcessStatus getStatus() {
54 | return status;
55 | }
56 |
57 | public void setStatus(ProcessStatus status) {
58 | this.status = status;
59 | }
60 |
61 | public Long getEventId() {
62 | return eventId;
63 | }
64 |
65 | public void setEventId(Long eventId) {
66 | this.eventId = eventId;
67 | }
68 |
69 | public EventType getEventType() {
70 | return eventType;
71 | }
72 |
73 | public void setEventType(EventType eventType) {
74 | this.eventType = eventType;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/EventWatchProcess.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import com.akkafun.common.domain.AuditEntity;
4 | import com.akkafun.common.event.constant.ProcessStatus;
5 |
6 | import javax.persistence.*;
7 |
8 | /**
9 | * Created by liubin on 2016/3/28.
10 | */
11 | @Entity
12 | @Table(name = "event_watch_process")
13 | public class EventWatchProcess extends AuditEntity {
14 |
15 | @Id
16 | @GeneratedValue(strategy = GenerationType.AUTO)
17 | private Long id;
18 |
19 | @Column
20 | private String failureInfo;
21 |
22 | @Column
23 | @Enumerated(EnumType.STRING)
24 | private ProcessStatus status = ProcessStatus.NEW;
25 |
26 | @Column
27 | private Long watchId;
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 getFailureInfo() {
38 | return failureInfo;
39 | }
40 |
41 | public void setFailureInfo(String failureInfo) {
42 | this.failureInfo = failureInfo;
43 | }
44 |
45 | public ProcessStatus getStatus() {
46 | return status;
47 | }
48 |
49 | public void setStatus(ProcessStatus status) {
50 | this.status = status;
51 | }
52 |
53 | public Long getWatchId() {
54 | return watchId;
55 | }
56 |
57 | public void setWatchId(Long watchId) {
58 | this.watchId = watchId;
59 | }
60 |
61 |
62 | @Override
63 | public String toString() {
64 | return "EventWatchProcess{" +
65 | "watchId=" + watchId +
66 | ", status=" + status +
67 | ", failureInfo='" + failureInfo + '\'' +
68 | ", id=" + id +
69 | "} " + super.toString();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/NotifyEventPublish.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import javax.persistence.DiscriminatorValue;
4 | import javax.persistence.Entity;
5 |
6 | /**
7 | * Created by liubin on 2016/3/28.
8 | */
9 | @Entity
10 | @DiscriminatorValue("NOTIFY")
11 | public class NotifyEventPublish extends EventPublish {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/domain/RevokeAskEventPublish.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.domain;
2 |
3 | import javax.persistence.Column;
4 | import javax.persistence.DiscriminatorValue;
5 | import javax.persistence.Entity;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @Entity
11 | @DiscriminatorValue("REVOKE")
12 | public class RevokeAskEventPublish extends EventPublish {
13 |
14 | @Column
15 | private Long askEventId;
16 |
17 | public Long getAskEventId() {
18 | return askEventId;
19 | }
20 |
21 | public void setAskEventId(Long askEventId) {
22 | this.askEventId = askEventId;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/handler/AskEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.handler;
2 |
3 | import com.akkafun.base.api.BooleanWrapper;
4 | import com.akkafun.base.event.domain.AskEvent;
5 |
6 | /**
7 | * Created by liubin on 2016/6/3.
8 | */
9 | public interface AskEventHandler {
10 |
11 | BooleanWrapper processRequest(E event);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/handler/NotifyEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.handler;
2 |
3 | import com.akkafun.base.event.domain.NotifyEvent;
4 |
5 | /**
6 | * Created by liubin on 2016/6/3.
7 | */
8 | public interface NotifyEventHandler {
9 |
10 | void notify(E event);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/handler/RevokableAskEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.handler;
2 |
3 | import com.akkafun.base.event.constants.FailureInfo;
4 | import com.akkafun.base.event.domain.AskEvent;
5 | import com.akkafun.base.event.domain.Revokable;
6 |
7 | /**
8 | * Created by liubin on 2016/6/3.
9 | */
10 | public interface RevokableAskEventHandler extends AskEventHandler {
11 |
12 | void processRevoke(E originEvent, FailureInfo failureInfo);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/scheduler/EventScheduler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.scheduler;
2 |
3 | import com.akkafun.common.event.service.EventBus;
4 | import com.akkafun.common.event.service.EventWatchService;
5 | import org.springframework.scheduling.annotation.Scheduled;
6 |
7 | /**
8 | * Created by liubin on 2016/4/19.
9 | */
10 | public class EventScheduler{
11 |
12 | EventBus eventBus;
13 |
14 | public EventScheduler(EventBus eventBus) {
15 | this.eventBus = eventBus;
16 | }
17 |
18 | @Scheduled(fixedRate = 500L)
19 | public void sendUnpublishedEvent() {
20 | eventBus.sendUnpublishedEvent();
21 | }
22 |
23 | @Scheduled(fixedRate = 500L)
24 | public void searchAndHandleUnprocessedEvent() {
25 | eventBus.searchAndHandleUnprocessedEvent();
26 | }
27 |
28 | @Scheduled(fixedRate = 500L)
29 | public void handleUnprocessedEventWatchProcess() {
30 | eventBus.handleUnprocessedEventWatchProcess();
31 | }
32 |
33 | @Scheduled(fixedRate = 1000L)
34 | public void handleTimeoutEventWatch() {
35 | eventBus.handleTimeoutEventWatch();
36 | }
37 |
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/event/service/EventHandlerExecutor.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.service;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.stereotype.Service;
6 | import org.springframework.transaction.annotation.Propagation;
7 | import org.springframework.transaction.annotation.Transactional;
8 |
9 | import java.util.function.Supplier;
10 |
11 | /**
12 | * Created by liubin on 2016/6/30.
13 | */
14 | @Service
15 | public class EventHandlerExecutor {
16 |
17 | private static Logger logger = LoggerFactory.getLogger(EventHandlerExecutor.class);
18 |
19 |
20 | /**
21 | * 执行handler处理
22 | * @param supplier
23 | */
24 | @Transactional(propagation = Propagation.REQUIRES_NEW)
25 | public T executeEventHandler(Supplier supplier){
26 |
27 | return supplier.get();
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/exception/EventException.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.exception;
2 |
3 | import com.akkafun.base.exception.BaseException;
4 |
5 | /**
6 | * Created by liubin on 2016/4/14.
7 | */
8 | public class EventException extends BaseException {
9 |
10 | public EventException(String message) {
11 | super(message);
12 | }
13 |
14 | public EventException(String message, Throwable cause) {
15 | super(message, cause);
16 | }
17 |
18 | public EventException(Throwable cause) {
19 | super(cause);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/scheduler/config/SchedulerConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.scheduler.config;
2 |
3 | import com.akkafun.common.event.scheduler.EventScheduler;
4 | import com.akkafun.common.event.service.EventBus;
5 | import com.akkafun.common.event.service.EventWatchService;
6 | import com.akkafun.common.scheduler.ZkCoordinateScheduledExecutor;
7 | import com.akkafun.common.scheduler.ZkSchedulerCoordinator;
8 | import com.akkafun.common.spring.ApplicationConstant;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.scheduling.TaskScheduler;
11 | import org.springframework.scheduling.annotation.EnableScheduling;
12 | import org.springframework.scheduling.annotation.SchedulingConfigurer;
13 | import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
14 | import org.springframework.scheduling.config.ScheduledTaskRegistrar;
15 |
16 | /**
17 | * Created by liubin on 2016/4/8.
18 | */
19 | @EnableScheduling
20 | public class SchedulerConfiguration implements SchedulingConfigurer {
21 |
22 |
23 | @Bean
24 | public ZkSchedulerCoordinator zkSchedulerCoordinator(ApplicationConstant applicationConstant){
25 |
26 | return new ZkSchedulerCoordinator(applicationConstant);
27 |
28 | }
29 |
30 | @Bean
31 | public EventScheduler eventScheduler(EventBus eventBus) {
32 | return new EventScheduler(eventBus);
33 | }
34 |
35 |
36 | @Override
37 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
38 |
39 | TaskScheduler taskScheduler = new ConcurrentTaskScheduler(new ZkCoordinateScheduledExecutor(5));
40 | taskRegistrar.setTaskScheduler(taskScheduler);
41 |
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/ApplicationConstant.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 |
5 | /**
6 | * Created by liubin on 2016/4/20.
7 | */
8 | public class ApplicationConstant {
9 |
10 | @Value("${spring.cloud.stream.kafka.binder.zkNodes:}")
11 | public String zkAddress;
12 |
13 | @Value("${spring.application.name}")
14 | public String applicationName;
15 |
16 | @Value("${spring.application.index}")
17 | public int applicationIndex;
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/ApplicationContextHolder.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring;
2 |
3 | import org.springframework.beans.BeansException;
4 | import org.springframework.context.ApplicationContext;
5 | import org.springframework.context.ApplicationContextAware;
6 |
7 | /**
8 | * Created by liubin on 2016/4/14.
9 | */
10 | public class ApplicationContextHolder implements ApplicationContextAware {
11 |
12 | public static ApplicationContext context;
13 |
14 | public static ApplicationConstant constant;
15 |
16 | public static final ApplicationContextHolder INSTANCE = new ApplicationContextHolder();
17 |
18 | private ApplicationContextHolder(){}
19 |
20 | public static ApplicationContextHolder getInstance() {
21 | return INSTANCE;
22 | }
23 |
24 | @Override
25 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
26 | context = applicationContext;
27 | constant = applicationContext.getBean(ApplicationConstant.class);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/BaseConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring;
2 |
3 | import com.akkafun.common.utils.JsonUtils;
4 | import com.akkafun.common.utils.spring.CustomRestTemplate;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import org.springframework.boot.orm.jpa.EntityScan;
7 | import org.springframework.cloud.client.loadbalancer.LoadBalanced;
8 | import org.springframework.cloud.netflix.hystrix.EnableHystrix;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.ComponentScan;
11 | import org.springframework.context.annotation.Primary;
12 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
13 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
14 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
15 | import org.springframework.web.client.RestTemplate;
16 |
17 | /**
18 | * Created by liubin on 2016/3/28.
19 | */
20 | @EntityScan(basePackages = {
21 | "com.akkafun.**.domain",
22 | "org.springframework.data.jpa.convert.threeten"
23 | })
24 | @EnableJpaRepositories("com.akkafun.**.dao")
25 | @EnableJpaAuditing
26 | @EnableHystrix
27 | @ComponentScan({"com.akkafun.**.service", "com.akkafun.**.web"})
28 | public class BaseConfiguration {
29 |
30 | @Bean
31 | public ApplicationConstant applicationConstant() {
32 | return new ApplicationConstant();
33 | }
34 |
35 | @Bean
36 | public ApplicationContextHolder applicationContextHolder() {
37 | return ApplicationContextHolder.getInstance();
38 | }
39 |
40 | //customize object mapper
41 | @Bean
42 | @Primary
43 | public ObjectMapper objectMapper() {
44 | return JsonUtils.OBJECT_MAPPER;
45 | }
46 |
47 | @LoadBalanced
48 | @Bean
49 | public RestTemplate restTemplate(MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter) {
50 |
51 | return CustomRestTemplate.assembleRestTemplate(mappingJackson2HttpMessageConverter);
52 | }
53 |
54 | @Bean
55 | public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
56 | return new MappingJackson2HttpMessageConverter(objectMapper());
57 | }
58 |
59 |
60 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/ServiceClientConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring;
2 |
3 | import com.netflix.appinfo.ApplicationInfoManager;
4 | import com.netflix.discovery.DiscoveryClient;
5 | import com.netflix.discovery.EurekaClient;
6 | import com.netflix.discovery.EurekaClientConfig;
7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
8 | import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
9 | import org.springframework.cloud.netflix.feign.EnableFeignClients;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.annotation.Bean;
12 |
13 | /**
14 | * Created by liubin on 2016/5/30.
15 | */
16 | @EnableDiscoveryClient
17 | @EnableFeignClients("com.akkafun.**.service")
18 | public class ServiceClientConfiguration {
19 |
20 | @Bean(destroyMethod = "shutdown")
21 | @org.springframework.cloud.context.config.annotation.RefreshScope
22 | public EurekaClient eurekaClient(ApplicationInfoManager manager,
23 | EurekaClientConfig config,
24 | DiscoveryClient.DiscoveryClientOptionalArgs optionalArgs,
25 | ApplicationContext context) {
26 | manager.getInfo(); // force initialization
27 | return new CloudEurekaClient(manager, config, optionalArgs, context);
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/WebApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring;
2 |
3 | import com.akkafun.common.spring.mvc.AppErrorController;
4 | import com.akkafun.common.spring.mvc.AppExceptionHandlerController;
5 | import org.springframework.boot.autoconfigure.web.ErrorAttributes;
6 | import org.springframework.boot.autoconfigure.web.ErrorController;
7 | import org.springframework.boot.autoconfigure.web.ServerProperties;
8 | import org.springframework.context.annotation.Bean;
9 | import springfox.documentation.builders.PathSelectors;
10 | import springfox.documentation.spi.DocumentationType;
11 | import springfox.documentation.spring.web.plugins.Docket;
12 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
13 |
14 | import java.time.LocalDate;
15 | import java.time.LocalDateTime;
16 |
17 | /**
18 | * Created by liubin on 2016/3/28.
19 | */
20 | @EnableSwagger2
21 | public class WebApplication {
22 |
23 | //error page
24 | @Bean
25 | public ErrorController errorController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
26 | return new AppErrorController(errorAttributes, serverProperties.getError());
27 | }
28 |
29 | //exception handler
30 | @Bean
31 | public AppExceptionHandlerController appExceptionHandlerController() {
32 | return new AppExceptionHandlerController();
33 | }
34 |
35 | @Bean
36 | public Docket api() {
37 | return new Docket(DocumentationType.SWAGGER_2)
38 | .directModelSubstitute(LocalDate.class, java.sql.Date.class)
39 | .directModelSubstitute(LocalDateTime.class, java.util.Date.class)
40 | .select()
41 | .apis(requestHandler -> {
42 | String packageName = requestHandler.getHandlerMethod().getMethod()
43 | .getDeclaringClass().getPackage().getName();
44 | return packageName.startsWith("com.akkafun.") && packageName.contains(".web");
45 | })
46 | .paths(PathSelectors.any())
47 | .build();
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/spring/utils/InnerClassPathScanningCandidateComponentProvider.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.spring.utils;
2 |
3 | import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
4 | import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
5 | import org.springframework.core.env.Environment;
6 |
7 | /**
8 | * 内部类也能查询出来
9 | * Created by liubin on 2016/5/31.
10 | */
11 | public class InnerClassPathScanningCandidateComponentProvider extends ClassPathScanningCandidateComponentProvider {
12 |
13 | public InnerClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) {
14 | super(useDefaultFilters);
15 | }
16 |
17 | public InnerClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {
18 | super(useDefaultFilters, environment);
19 | }
20 |
21 | @Override
22 | protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
23 | return beanDefinition.getMetadata().isConcrete();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/callbacks/AskTestEventFirstCallback.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.callbacks;
2 |
3 | import com.akkafun.common.test.domain.AskTestEvent;
4 | import com.google.common.collect.Lists;
5 |
6 | import java.util.List;
7 | import java.util.concurrent.CopyOnWriteArrayList;
8 |
9 | /**
10 | * Created by liubin on 2016/6/16.
11 | */
12 | public class AskTestEventFirstCallback {
13 |
14 | public static final List successParams = new CopyOnWriteArrayList<>();
15 |
16 | public void onSuccess(AskTestEvent event) {
17 | CallbackParam callbackParam = new CallbackParam(Lists.newArrayList(event), null, null);
18 | successParams.add(callbackParam);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/callbacks/AskTestEventSecondCallback.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.callbacks;
2 |
3 | import com.akkafun.base.event.constants.FailureInfo;
4 | import com.akkafun.common.test.domain.AskTestEvent;
5 | import com.google.common.collect.Lists;
6 |
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 | import java.util.concurrent.CopyOnWriteArrayList;
11 |
12 | /**
13 | * Created by liubin on 2016/6/16.
14 | */
15 | public class AskTestEventSecondCallback {
16 |
17 | public static final List successParams = new CopyOnWriteArrayList<>();
18 | public static final List failureParams = new CopyOnWriteArrayList<>();
19 |
20 |
21 | public void onSuccess(AskTestEvent event, String param1, String param2) {
22 | Map params = new HashMap<>();
23 | params.put("param1", param1);
24 | params.put("param2", param2);
25 | CallbackParam callbackParam = new CallbackParam(Lists.newArrayList(event), null, params);
26 | successParams.add(callbackParam);
27 | }
28 |
29 | public void onFailure(AskTestEvent event, FailureInfo failureInfo, String param3, String param4) {
30 | Map params = new HashMap<>();
31 | params.put("param3", param3);
32 | params.put("param4", param4);
33 | CallbackParam callbackParam = new CallbackParam(Lists.newArrayList(event), failureInfo, params);
34 | failureParams.add(callbackParam);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/callbacks/CallbackParam.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.callbacks;
2 |
3 | import com.akkafun.base.event.constants.FailureInfo;
4 | import com.akkafun.base.event.domain.AskEvent;
5 |
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | /**
11 | * Created by liubin on 2016/6/17.
12 | */
13 | public class CallbackParam {
14 |
15 | private List askEvents;
16 |
17 | private FailureInfo failureInfo;
18 |
19 | private Map params;
20 |
21 | public CallbackParam(List askEvents, FailureInfo failureInfo, Map params) {
22 | this.askEvents = askEvents;
23 | this.failureInfo = failureInfo;
24 | this.params = params == null ? new HashMap<>() : params;
25 | }
26 |
27 |
28 | public List getAskEvents() {
29 | return askEvents;
30 | }
31 |
32 | public FailureInfo getFailureInfo() {
33 | return failureInfo;
34 | }
35 |
36 | public Map getParams() {
37 | return params;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/callbacks/UnitedTestEventCallback.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.callbacks;
2 |
3 | import com.akkafun.base.event.constants.FailureInfo;
4 | import com.akkafun.common.test.domain.AskTestEvent;
5 | import com.akkafun.common.test.domain.RevokableAskTestEvent;
6 | import com.google.common.collect.Lists;
7 |
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 | import java.util.concurrent.CopyOnWriteArrayList;
12 |
13 | /**
14 | * Created by liubin on 2016/6/16.
15 | */
16 | public class UnitedTestEventCallback {
17 |
18 | public static final String SUCCESS_EVENT_NAME = "克尔苏加德";
19 |
20 | public static final List successParams = new CopyOnWriteArrayList<>();
21 | public static final List failureParams = new CopyOnWriteArrayList<>();
22 |
23 |
24 | public void onSuccess(AskTestEvent askTestEvent, RevokableAskTestEvent revokableAskTestEvent,
25 | String param1, String param2) {
26 | Map params = new HashMap<>();
27 | params.put("param1", param1);
28 | params.put("param2", param2);
29 | CallbackParam callbackParam = new CallbackParam(Lists.newArrayList(askTestEvent, revokableAskTestEvent),
30 | null, params);
31 | successParams.add(callbackParam);
32 | }
33 |
34 | public void onFailure(AskTestEvent askTestEvent, RevokableAskTestEvent revokableAskTestEvent,
35 | FailureInfo failureInfo, String param3, String param4) {
36 | Map params = new HashMap<>();
37 | params.put("param3", param3);
38 | params.put("param4", param4);
39 | CallbackParam callbackParam = new CallbackParam(Lists.newArrayList(askTestEvent, revokableAskTestEvent),
40 | failureInfo, params);
41 | failureParams.add(callbackParam);
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/domain/AskTestEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.AskEvent;
5 | import com.fasterxml.jackson.annotation.JsonCreator;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 |
8 | public class AskTestEvent extends AskEvent {
9 |
10 | public static final EventType EVENT_TYPE = EventType.ASK_TEST_EVENT;
11 |
12 | @Override
13 | public EventType getType() {
14 | return EVENT_TYPE;
15 | }
16 |
17 | private String name;
18 |
19 | @JsonCreator
20 | public AskTestEvent(
21 | @JsonProperty("name") String name){
22 | this.name = name;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "AskTestEvent{" +
32 | "name='" + name + '\'' +
33 | "} " + super.toString();
34 | }
35 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/domain/NotifyFirstTestEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.NotifyEvent;
5 | import com.fasterxml.jackson.annotation.JsonCreator;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 |
8 | import java.time.LocalDateTime;
9 |
10 | public class NotifyFirstTestEvent extends NotifyEvent {
11 |
12 | public static final EventType EVENT_TYPE = EventType.NOTIFY_FIRST_TEST_EVENT;
13 |
14 | @Override
15 | public EventType getType() {
16 | return EVENT_TYPE;
17 | }
18 |
19 | private String name;
20 |
21 | private LocalDateTime registerTime;
22 |
23 | @JsonCreator
24 | public NotifyFirstTestEvent(
25 | @JsonProperty("name") String name,
26 | @JsonProperty("registerTime") LocalDateTime registerTime) {
27 | this.name = name;
28 | this.registerTime = registerTime;
29 | }
30 |
31 | public String getName() {
32 | return name;
33 | }
34 |
35 | public LocalDateTime getRegisterTime() {
36 | return registerTime;
37 | }
38 |
39 | @Override
40 | public String toString() {
41 | return "NotifyFirstTestEvent{" +
42 | "name='" + name + '\'' +
43 | ", registerTime=" + registerTime +
44 | "} " + super.toString();
45 | }
46 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/domain/NotifySecondTestEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.NotifyEvent;
5 | import com.fasterxml.jackson.annotation.JsonCreator;
6 | import com.fasterxml.jackson.annotation.JsonProperty;
7 |
8 | public class NotifySecondTestEvent extends NotifyEvent {
9 |
10 | public static final EventType EVENT_TYPE = EventType.NOTIFY_SECOND_TEST_EVENT;
11 |
12 | @Override
13 | public EventType getType() {
14 | return EVENT_TYPE;
15 | }
16 |
17 | private String name;
18 |
19 | @JsonCreator
20 | public NotifySecondTestEvent(
21 | @JsonProperty("name") String name) {
22 | this.name = name;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "NotifySecondTestEvent{" +
32 | "name='" + name + '\'' +
33 | "} " + super.toString();
34 | }
35 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/domain/RevokableAskTestEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.domain;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.AskEvent;
5 | import com.akkafun.base.event.domain.Revokable;
6 | import com.fasterxml.jackson.annotation.JsonCreator;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | public class RevokableAskTestEvent extends AskEvent implements Revokable {
10 |
11 | public static final EventType EVENT_TYPE = EventType.REVOKABLE_ASK_TEST_EVENT;
12 |
13 | @Override
14 | public EventType getType() {
15 | return EVENT_TYPE;
16 | }
17 |
18 | private String name;
19 |
20 | @JsonCreator
21 | public RevokableAskTestEvent(
22 | @JsonProperty("name") String name){
23 | this.name = name;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return "RevokableAskTestEvent{" +
33 | "name='" + name + '\'' +
34 | "} " + super.toString();
35 | }
36 | }
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/handlers/AskTestEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.handlers;
2 |
3 | import com.akkafun.base.api.BooleanWrapper;
4 | import com.akkafun.common.event.handler.AskEventHandler;
5 | import com.akkafun.common.test.domain.AskTestEvent;
6 |
7 | import java.util.List;
8 | import java.util.concurrent.CopyOnWriteArrayList;
9 |
10 | /**
11 | * Created by liubin on 2016/6/15.
12 | */
13 | public class AskTestEventHandler implements AskEventHandler {
14 |
15 | public static final String SUCCESS_EVENT_NAME = "克尔苏加德";
16 |
17 | public static final List events = new CopyOnWriteArrayList<>();
18 |
19 | @Override
20 | public BooleanWrapper processRequest(AskTestEvent event) {
21 | events.add(event);
22 | return new BooleanWrapper(event.getName().equals(SUCCESS_EVENT_NAME));
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/handlers/NotifyFirstTestEventFirstHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.handlers;
2 |
3 | import com.akkafun.common.event.handler.NotifyEventHandler;
4 | import com.akkafun.common.test.domain.NotifyFirstTestEvent;
5 |
6 | import java.util.List;
7 | import java.util.concurrent.CopyOnWriteArrayList;
8 |
9 | /**
10 | * Created by liubin on 2016/6/15.
11 | */
12 | public class NotifyFirstTestEventFirstHandler implements NotifyEventHandler {
13 |
14 | public static final List events = new CopyOnWriteArrayList<>();
15 |
16 | @Override
17 | public void notify(NotifyFirstTestEvent event) {
18 | events.add(event);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/handlers/NotifyFirstTestEventSecondHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.handlers;
2 |
3 | import com.akkafun.common.event.handler.NotifyEventHandler;
4 | import com.akkafun.common.test.domain.NotifyFirstTestEvent;
5 |
6 | import java.util.List;
7 | import java.util.concurrent.CopyOnWriteArrayList;
8 |
9 | /**
10 | * Created by liubin on 2016/6/15.
11 | */
12 | public class NotifyFirstTestEventSecondHandler implements NotifyEventHandler {
13 |
14 | public static final List events = new CopyOnWriteArrayList<>();
15 |
16 | @Override
17 | public void notify(NotifyFirstTestEvent event) {
18 | events.add(event);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/handlers/NotifySecondTestEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.handlers;
2 |
3 | import com.akkafun.common.event.handler.NotifyEventHandler;
4 | import com.akkafun.common.test.domain.NotifySecondTestEvent;
5 |
6 | /**
7 | * Created by liubin on 2016/6/15.
8 | */
9 | public class NotifySecondTestEventHandler implements NotifyEventHandler {
10 |
11 | @Override
12 | public void notify(NotifySecondTestEvent event) {
13 |
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/common/src/main/java/com/akkafun/common/test/handlers/RevokableAskTestEventHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test.handlers;
2 |
3 | import com.akkafun.base.api.BooleanWrapper;
4 | import com.akkafun.base.event.constants.FailureInfo;
5 | import com.akkafun.common.event.handler.RevokableAskEventHandler;
6 | import com.akkafun.common.test.domain.RevokableAskTestEvent;
7 |
8 | import java.util.List;
9 | import java.util.concurrent.CopyOnWriteArrayList;
10 |
11 | /**
12 | * Created by liubin on 2016/6/15.
13 | */
14 | public class RevokableAskTestEventHandler implements RevokableAskEventHandler {
15 |
16 |
17 | public static final String SUCCESS_EVENT_NAME = "克尔苏加德";
18 |
19 | public static final List events = new CopyOnWriteArrayList<>();
20 | public static final List revokeEvents = new CopyOnWriteArrayList<>();
21 |
22 |
23 | @Override
24 | public void processRevoke(RevokableAskTestEvent originEvent, FailureInfo failureInfo) {
25 | revokeEvents.add(originEvent);
26 | }
27 |
28 | @Override
29 | public BooleanWrapper processRequest(RevokableAskTestEvent event) {
30 | events.add(event);
31 | return new BooleanWrapper(event.getName().equals(SUCCESS_EVENT_NAME));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/common/src/test/java/com/akkafun/common/event/EventTestUtils.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event;
2 |
3 | import com.akkafun.common.test.callbacks.AskTestEventFirstCallback;
4 | import com.akkafun.common.test.callbacks.AskTestEventSecondCallback;
5 | import com.akkafun.common.test.callbacks.UnitedTestEventCallback;
6 | import com.akkafun.common.test.handlers.AskTestEventHandler;
7 | import com.akkafun.common.test.handlers.NotifyFirstTestEventFirstHandler;
8 | import com.akkafun.common.test.handlers.NotifyFirstTestEventSecondHandler;
9 | import com.akkafun.common.test.handlers.RevokableAskTestEventHandler;
10 |
11 | /**
12 | * Created by liubin on 2016/6/17.
13 | */
14 | public class EventTestUtils {
15 |
16 | public static void clear() {
17 | AskTestEventFirstCallback.successParams.clear();
18 | AskTestEventSecondCallback.successParams.clear();
19 | AskTestEventSecondCallback.failureParams.clear();
20 | UnitedTestEventCallback.successParams.clear();
21 | UnitedTestEventCallback.failureParams.clear();
22 | AskTestEventHandler.events.clear();
23 | NotifyFirstTestEventFirstHandler.events.clear();
24 | NotifyFirstTestEventSecondHandler.events.clear();
25 | RevokableAskTestEventHandler.events.clear();
26 | RevokableAskTestEventHandler.revokeEvents.clear();
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/common/src/test/java/com/akkafun/common/event/EventUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event;
2 |
3 | import com.akkafun.common.test.domain.NotifyFirstTestEvent;
4 | import org.junit.Test;
5 |
6 | import java.time.LocalDateTime;
7 |
8 | import static org.hamcrest.Matchers.is;
9 | import static org.junit.Assert.assertThat;
10 |
11 |
12 | /**
13 | * Created by liubin on 2016/4/11.
14 | */
15 | public class EventUtilsTest {
16 |
17 |
18 | @Test
19 | public void testSerialize() {
20 |
21 | NotifyFirstTestEvent testEventFirst = new NotifyFirstTestEvent("张三", LocalDateTime.now());
22 |
23 | String json = EventUtils.serializeEvent(testEventFirst);
24 |
25 | NotifyFirstTestEvent testEventFirstFromJson = EventUtils.deserializeEvent(json, NotifyFirstTestEvent.class);
26 |
27 | assertThat(testEventFirstFromJson, is(testEventFirst));
28 |
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/common/src/test/java/com/akkafun/common/test/BaseControllerTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test;
2 |
3 | import com.akkafun.common.spring.WebApplication;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.boot.test.SpringApplicationConfiguration;
6 | import org.springframework.boot.test.WebIntegrationTest;
7 | import org.springframework.http.HttpEntity;
8 | import org.springframework.http.HttpHeaders;
9 | import org.springframework.http.MediaType;
10 |
11 | /**
12 | * Created by liubin on 2016/3/30.
13 | */
14 | @WebIntegrationTest(randomPort = true)
15 | @SpringApplicationConfiguration(classes = WebApplication.class)
16 | public abstract class BaseControllerTest extends BaseTest {
17 |
18 | @Value("${local.server.port}")
19 | protected int serverPort;
20 |
21 | protected String localServerUrl(){
22 | return String.format("http://localhost:%d", serverPort);
23 | }
24 |
25 | protected String buildRequestUrl(String url) {
26 | return String.format("%s/%s", localServerUrl(), url);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/common/src/test/java/com/akkafun/common/test/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.test;
2 |
3 | import com.akkafun.common.event.service.EventBus;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
7 |
8 | /**
9 | * Created by liubin on 2016/3/29.
10 | */
11 | @RunWith(SpringJUnit4ClassRunner.class)
12 | public abstract class BaseTest {
13 |
14 | @Autowired
15 | protected EventBus eventBus;
16 |
17 | /**
18 | * 发送事件并等待
19 | */
20 | protected void sendEvent() {
21 |
22 | eventBus.sendUnpublishedEvent();
23 | try {
24 | Thread.sleep(3000L);
25 | } catch (InterruptedException e) {
26 | throw new RuntimeException(e);
27 | }
28 |
29 | }
30 |
31 | /**
32 | * 异步处理事件并等待
33 | */
34 | protected void handleEvent() {
35 |
36 | try {
37 | eventBus.searchAndHandleUnprocessedEvent();
38 | Thread.sleep(3000L);
39 | eventBus.handleUnprocessedEventWatchProcess();
40 | Thread.sleep(3000L);
41 | } catch (InterruptedException e) {
42 | throw new RuntimeException(e);
43 | }
44 |
45 | }
46 |
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/config/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | config
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | base
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 | com.akkafun.config.ConfigApplication
16 |
17 |
18 |
19 |
20 | org.springframework.cloud
21 | spring-cloud-config-server
22 |
23 |
24 | org.springframework.cloud
25 | spring-cloud-config-monitor
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-starter-eureka
30 |
31 |
32 | org.springframework.cloud
33 | spring-cloud-starter-stream-kafka
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/config/src/main/java/com/akkafun/config/ConfigApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.config;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.config.server.EnableConfigServer;
7 |
8 | @SpringBootApplication
9 | @EnableDiscoveryClient
10 | @EnableConfigServer
11 | public class ConfigApplication {
12 |
13 | /**
14 | * Run the application using Spring Boot and an embedded servlet engine.
15 | *
16 | * @param args
17 | * Program arguments - ignored.
18 | */
19 | public static void main(String[] args) {
20 | SpringApplication.run(ConfigApplication.class, args);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/config/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8888
3 |
4 | spring:
5 | application:
6 | name: config
7 |
8 | cloud:
9 | config:
10 | server:
11 | git:
12 | uri: https://github.com/sunnykaka/mysteam-config-repo
13 | # uri: file:///D:/opensource/workspace/mysteam-config-repo
14 | basedir: target/config
15 | searchPaths: "*"
16 |
17 | stream:
18 | instanceCount: 1
19 | instanceIndex: 0
20 | kafka:
21 | binder:
22 | brokers: 192.168.239.129:9092,192.168.239.129:9093,192.168.239.129:9094
23 | zkNodes: 192.168.239.129:2181
24 | offsetUpdateTimeWindow: 10000
25 | #offsetUpdateCount: 0
26 | requiredAcks: 1
27 | minPartitionCount: 1
28 | replicationFactor: 1
29 |
30 | bindings:
31 | input:
32 | consumer:
33 | autoCommitOffset: true
34 | startOffset: earliest
35 | headerMode: raw
36 | output:
37 | producer:
38 | bufferSize: 16384
39 | sync: true
40 | batchTimeout: 0
41 |
42 |
43 | management:
44 | context-path: /admin
45 |
46 | logging:
47 | level:
48 | com.netflix.discovery: 'OFF'
49 | org.springframework.cloud: 'DEBUG'
50 |
51 | eureka:
52 | instance:
53 | preferIpAddress: true
54 | leaseRenewalIntervalInSeconds: 10
55 | statusPageUrlPath: /admin/info
56 | healthCheckUrlPath: /admin/health
57 |
58 | client:
59 | serviceUrl:
60 | defaultZone: http://localhost:1111/eureka/
61 |
--------------------------------------------------------------------------------
/coupon/api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | coupon-service-api
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | coupon-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.akkafun.mysteam
19 | apiutils
20 | ${project.version}
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/coupon/api/src/main/java/com/akkafun/coupon/api/CouponUrl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/6.
5 | */
6 | public interface CouponUrl {
7 |
8 | String SERVICE_NAME = "COUPON";
9 |
10 | String SERVICE_HOSTNAME = "http://COUPON";
11 |
12 | String CHECK_VALID_URL = "/coupons/{couponId}/valid";
13 |
14 | String COUPON_LIST_URL = "/coupons";
15 |
16 | String USER_COUPON_LIST_URL = "/coupons/{userId}";
17 |
18 | static String buildUrl(String url) {
19 | return SERVICE_HOSTNAME + url;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/coupon/api/src/main/java/com/akkafun/coupon/api/constants/CouponState.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.api.constants;
2 |
3 | /**
4 | * Created by liubin on 2016/4/26.
5 | */
6 | public enum CouponState {
7 |
8 | VALID("有效"),
9 |
10 | USED("已使用"),
11 |
12 | INVALID("已失效");
13 |
14 | public String desc;
15 |
16 | CouponState(String desc) {
17 | this.desc = desc;
18 | }
19 |
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/coupon/api/src/main/java/com/akkafun/coupon/api/events/AskUseCoupon.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.api.events;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.AskEvent;
5 | import com.akkafun.base.event.domain.Revokable;
6 | import com.fasterxml.jackson.annotation.JsonCreator;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Created by liubin on 2016/4/8.
13 | */
14 | public class AskUseCoupon extends AskEvent implements Revokable {
15 |
16 | public static final EventType EVENT_TYPE = EventType.ASK_USE_COUPON;
17 |
18 | @Override
19 | public EventType getType() {
20 | return EVENT_TYPE;
21 | }
22 |
23 | private List couponIds;
24 |
25 | private Long userId;
26 |
27 | private Long orderId;
28 |
29 | @JsonCreator
30 | public AskUseCoupon(
31 | @JsonProperty("couponIds") List couponIds,
32 | @JsonProperty("userId") Long userId,
33 | @JsonProperty("orderId") Long orderId) {
34 | this.couponIds = couponIds;
35 | this.userId = userId;
36 | this.orderId = orderId;
37 | }
38 |
39 | public List getCouponIds() {
40 | return couponIds;
41 | }
42 |
43 | public Long getUserId() {
44 | return userId;
45 | }
46 |
47 | public Long getOrderId() {
48 | return orderId;
49 | }
50 |
51 | @Override
52 | public String toString() {
53 | return "AskUseCoupon{" +
54 | "couponIds=" + couponIds +
55 | ", userId=" + userId +
56 | ", orderId=" + orderId +
57 | "} " + super.toString();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/coupon/core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | coupon-service-core
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | coupon-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 | com.akkafun.coupon.context.CouponApplication
17 |
18 |
19 |
20 |
21 |
22 | mysql
23 | mysql-connector-java
24 | runtime
25 |
26 |
27 |
28 | com.akkafun.mysteam
29 | common
30 | ${project.version}
31 |
32 |
33 |
34 | com.akkafun.mysteam
35 | common
36 | ${project.version}
37 | test-jar
38 | test
39 |
40 |
41 |
42 | com.akkafun.mysteam
43 | user-service-api
44 | ${project.version}
45 |
46 |
47 |
48 | com.akkafun.mysteam
49 | coupon-service-api
50 | ${project.version}
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | org.springframework.boot
61 | spring-boot-maven-plugin
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/context/CouponApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.context;
2 |
3 | import com.akkafun.common.event.config.EventConfiguration;
4 | import com.akkafun.common.scheduler.config.SchedulerConfiguration;
5 | import com.akkafun.common.spring.BaseConfiguration;
6 | import com.akkafun.common.spring.ServiceClientConfiguration;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.annotation.Import;
10 |
11 | /**
12 | * Created by liubin on 2016/3/28.
13 | */
14 | @SpringBootApplication
15 | @Import({BaseConfiguration.class, EventConfiguration.class, SchedulerConfiguration.class, ServiceClientConfiguration.class})
16 | public class CouponApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(CouponApplication.class, args);
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/dao/CouponRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.dao;
2 |
3 | import com.akkafun.coupon.domain.Coupon;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Created by liubin on 2016/4/26.
10 | */
11 | public interface CouponRepository extends PagingAndSortingRepository, CouponRepositoryCustom {
12 |
13 | List findByUserId(Long userId);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/dao/CouponRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/4/26.
7 | */
8 | public interface CouponRepositoryCustom extends AbstractRepository {
9 | }
10 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/dao/CouponRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public class CouponRepositoryImpl implements CouponRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 |
15 | @Override
16 | public EntityManager getEm() {
17 | return em;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/domain/Coupon.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.domain;
2 |
3 | import com.akkafun.common.domain.VersionEntity;
4 | import com.akkafun.coupon.api.constants.CouponState;
5 |
6 | import javax.persistence.*;
7 | import java.time.LocalDateTime;
8 |
9 | /**
10 | * Created by liubin on 2016/3/28.
11 | */
12 | @Entity
13 | @Table(name = "coupon")
14 | public class Coupon extends VersionEntity {
15 |
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.AUTO)
18 | private Long id;
19 |
20 | @Column
21 | private Long amount;
22 |
23 | @Column
24 | private Long userId;
25 |
26 | @Column
27 | @Enumerated(value = EnumType.STRING)
28 | private CouponState state;
29 |
30 | @Column
31 | private Long orderId;
32 |
33 | @Column
34 | private LocalDateTime useTime;
35 |
36 | @Column
37 | private String code;
38 |
39 | public Long getId() {
40 | return id;
41 | }
42 |
43 | public void setId(Long id) {
44 | this.id = id;
45 | }
46 |
47 | public Long getAmount() {
48 | return amount;
49 | }
50 |
51 | public void setAmount(Long amount) {
52 | this.amount = amount;
53 | }
54 |
55 | public Long getUserId() {
56 | return userId;
57 | }
58 |
59 | public void setUserId(Long userId) {
60 | this.userId = userId;
61 | }
62 |
63 | public CouponState getState() {
64 | return state;
65 | }
66 |
67 | public void setState(CouponState state) {
68 | this.state = state;
69 | }
70 |
71 | public Long getOrderId() {
72 | return orderId;
73 | }
74 |
75 | public void setOrderId(Long orderId) {
76 | this.orderId = orderId;
77 | }
78 |
79 | public LocalDateTime getUseTime() {
80 | return useTime;
81 | }
82 |
83 | public void setUseTime(LocalDateTime useTime) {
84 | this.useTime = useTime;
85 | }
86 |
87 | public String getCode() {
88 | return code;
89 | }
90 |
91 | public void setCode(String code) {
92 | this.code = code;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/handler/AskUseCouponHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.handler;
2 |
3 | import com.akkafun.base.api.BooleanWrapper;
4 | import com.akkafun.base.event.constants.FailureInfo;
5 | import com.akkafun.base.exception.AppBusinessException;
6 | import com.akkafun.common.event.handler.RevokableAskEventHandler;
7 | import com.akkafun.common.spring.ApplicationContextHolder;
8 | import com.akkafun.coupon.api.events.AskUseCoupon;
9 | import com.akkafun.coupon.service.CouponService;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 |
13 | /**
14 | * Created by liubin on 2016/6/24.
15 | */
16 | public class AskUseCouponHandler implements RevokableAskEventHandler {
17 |
18 | private static Logger logger = LoggerFactory.getLogger(AskUseCouponHandler.class);
19 |
20 |
21 | @Override
22 | public void processRevoke(AskUseCoupon originEvent, FailureInfo failureInfo) {
23 | logger.debug("AskUseCouponHandler processRevoke, receive AskUseCoupon: " + originEvent);
24 |
25 | CouponService couponService = ApplicationContextHolder.context.getBean(CouponService.class);
26 | couponService.revokeUse(originEvent.getCouponIds(), originEvent.getUserId(), originEvent.getOrderId());
27 | }
28 |
29 | @Override
30 | public BooleanWrapper processRequest(AskUseCoupon event) {
31 | logger.debug("AskUseCouponHandler processRequest, receive AskUseCoupon: " + event);
32 |
33 | if(event.getCouponIds() == null || event.getCouponIds().isEmpty()
34 | || event.getUserId() == null || event.getOrderId() == null) {
35 | return new BooleanWrapper(false, "couponId or userId or orderId is null");
36 | }
37 |
38 | CouponService couponService = ApplicationContextHolder.context.getBean(CouponService.class);
39 | couponService.useCoupon(event.getCouponIds(), event.getUserId(), event.getOrderId());
40 | return new BooleanWrapper(true);
41 |
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/coupon/core/src/main/java/com/akkafun/coupon/handler/UserCreatedHandler.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.coupon.handler;
2 |
3 | import com.akkafun.common.event.handler.NotifyEventHandler;
4 | import com.akkafun.common.spring.ApplicationContextHolder;
5 | import com.akkafun.coupon.service.CouponService;
6 | import com.akkafun.user.api.events.UserCreated;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | * Created by liubin on 2016/4/14.
12 | */
13 | public class UserCreatedHandler implements NotifyEventHandler {
14 |
15 | protected Logger logger = LoggerFactory.getLogger(UserCreatedHandler.class);
16 |
17 |
18 | @Override
19 | public void notify(UserCreated event) {
20 | CouponService couponService = ApplicationContextHolder.context.getBean(CouponService.class);
21 | couponService.initCoupon(event.getUserId());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/coupon/core/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: coupon
4 | cloud:
5 | config:
6 | uri: ${CONFIG_SERVER_URI:http://localhost:8888}
7 | failFast: true
8 | encrypt:
9 | failOnError: true
10 |
--------------------------------------------------------------------------------
/coupon/core/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/coupon-service.log
15 |
16 |
17 | logs/coupon-service-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/coupon/docs/coupon-service.sql:
--------------------------------------------------------------------------------
1 | /*==============================================================*/
2 | /* DBMS name: MySQL 5.0 */
3 | /* Created on: 2016/4/29 15:24:21 */
4 | /*==============================================================*/
5 |
6 |
7 | drop table if exists coupon;
8 |
9 | /*==============================================================*/
10 | /* Table: coupon */
11 | /*==============================================================*/
12 | create table coupon
13 | (
14 | id bigint unsigned not null auto_increment,
15 | amount bigint not null,
16 | userId bigint not null,
17 | state varchar(32) not null,
18 | orderId bigint,
19 | useTime datetime,
20 | code varchar(32),
21 | optlock int default 0,
22 | createTime datetime,
23 | updateTime datetime,
24 | primary key (id)
25 | );
26 |
27 |
--------------------------------------------------------------------------------
/coupon/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | coupon-service
6 |
7 | api
8 | core
9 |
10 | pom
11 |
12 |
13 | com.akkafun.mysteam
14 | base
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/docs/event.asta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangjianbinJAVA/mysteam/8b8abba1f0bdab215e638cdb30ad93f9ef267d6a/docs/event.asta
--------------------------------------------------------------------------------
/docs/init_database.sql:
--------------------------------------------------------------------------------
1 |
2 | create database if not exists user_service;
3 | use user_service;
4 | source user/docs/user-service.sql;
5 | source common/docs/common.sql;
6 |
7 | create database if not exists account_service;
8 | use account_service;
9 | source account/docs/account-service.sql;
10 | source common/docs/common.sql;
11 |
12 | create database if not exists coupon_service;
13 | use coupon_service;
14 | source coupon/docs/coupon-service.sql;
15 | source common/docs/common.sql;
16 |
17 | create database if not exists order_service;
18 | use order_service;
19 | source order/docs/order-service.sql;
20 | source common/docs/common.sql;
21 |
22 | create database if not exists product_service;
23 | use product_service;
24 | source product/docs/product-service.sql;
25 | source product/docs/init-product.sql;
26 | source common/docs/common.sql;
--------------------------------------------------------------------------------
/eureka/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | eureka
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | base
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 | com.akkafun.eureka.EurekaApplication
17 |
18 |
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-starter
30 |
31 |
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-starter-eureka-server
36 |
37 |
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-maven-plugin
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/eureka/src/main/java/com/akkafun/eureka/EurekaApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.eureka;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
6 |
7 | /**
8 | * All you need to run a Eureka registration server.
9 | *
10 | * @author Paul Chapman
11 | */
12 | @SpringBootApplication
13 | @EnableEurekaServer
14 | public class EurekaApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(EurekaApplication.class, args);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/eureka/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | # Configure this Discovery Server
2 | eureka:
3 | instance:
4 | # hostname: localhost
5 | preferIpAddress: true
6 | client: # Not a client, don't register with yourself
7 | registerWithEureka: false
8 | fetchRegistry: false
9 | serviceUrl:
10 | defaultZone: http://localhost:1111/eureka/
11 |
12 | server:
13 | enable-self-preservation: false
14 |
15 | server:
16 | port: 1111 # HTTP (Tomcat) port
17 |
18 | # Discovery Server Dashboard uses FreeMarker. Don't want Thymeleaf templates
19 | spring:
20 | thymeleaf:
21 | enabled: false # Disable Thymeleaf
--------------------------------------------------------------------------------
/eureka/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ${PID}: %-5level %logger{0} - %msg%n
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/integration-test/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/integration-test.log
15 |
16 |
17 | logs/integration-test-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/integration-test/src/test/java/com/akkafun/integrationtest/test/BaseIntegrationTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.integrationtest.test;
2 |
3 | import org.junit.runner.RunWith;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.boot.test.SpringApplicationConfiguration;
7 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
8 |
9 | /**
10 | * Created by liubin on 2016/3/29.
11 | */
12 | @RunWith(SpringJUnit4ClassRunner.class)
13 | @SpringApplicationConfiguration(classes = IntegrationTestApplication.class)
14 | public abstract class BaseIntegrationTest {
15 |
16 | protected Logger logger = LoggerFactory.getLogger(BaseIntegrationTest.class);
17 |
18 | protected void waitForEventProcessed() {
19 | try {
20 | Thread.sleep(20000L);
21 | } catch (InterruptedException e) {
22 | logger.error("", e);
23 | }
24 | }
25 |
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/order/api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | order-service-api
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | order-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.akkafun.mysteam
19 | apiutils
20 | ${project.version}
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/OrderUrl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/6.
5 | */
6 | public interface OrderUrl {
7 |
8 | String SERVICE_NAME = "ORDER";
9 |
10 | String SERVICE_HOSTNAME = "http://ORDER";
11 |
12 | String PLACE_ORDER = "/orders/place";
13 |
14 | String ORDER_INFO = "/orders/{orderId}";
15 |
16 | static String buildUrl(String url) {
17 | return SERVICE_HOSTNAME + url;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/constants/OrderStatus.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api.constants;
2 |
3 | /**
4 | * Created by liubin on 2016/4/26.
5 | */
6 | public enum OrderStatus {
7 |
8 | CREATE_PENDING("正在下单"),
9 |
10 | CREATED("已下单"),
11 |
12 | CREATE_FAILED("下单失败");
13 |
14 | public String desc;
15 |
16 | OrderStatus(String desc) {
17 | this.desc = desc;
18 | }
19 |
20 |
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/dtos/OrderItemDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api.dtos;
2 |
3 | /**
4 | * Created by liubin on 2016/3/28.
5 | */
6 | public class OrderItemDto {
7 |
8 | private Long id;
9 |
10 | private Long productId;
11 |
12 | private Long price;
13 |
14 | private int quantity;
15 |
16 | public Long getId() {
17 | return id;
18 | }
19 |
20 | public void setId(Long id) {
21 | this.id = id;
22 | }
23 |
24 | public Long getProductId() {
25 | return productId;
26 | }
27 |
28 | public void setProductId(Long productId) {
29 | this.productId = productId;
30 | }
31 |
32 | public Long getPrice() {
33 | return price;
34 | }
35 |
36 | public void setPrice(Long price) {
37 | this.price = price;
38 | }
39 |
40 | public int getQuantity() {
41 | return quantity;
42 | }
43 |
44 | public void setQuantity(int quantity) {
45 | this.quantity = quantity;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/dtos/PlaceOrderDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api.dtos;
2 |
3 | import org.hibernate.validator.constraints.NotEmpty;
4 |
5 | import javax.validation.Valid;
6 | import javax.validation.constraints.NotNull;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by liubin on 2016/5/6.
12 | */
13 | public class PlaceOrderDto {
14 |
15 | @NotNull(message = "用户ID不能为空")
16 | private Long userId;
17 |
18 | private List couponIdList = new ArrayList<>();
19 |
20 | @NotEmpty
21 | @Valid
22 | private List placeOrderItemList = new ArrayList<>(0);
23 |
24 | public Long getUserId() {
25 | return userId;
26 | }
27 |
28 | public void setUserId(Long userId) {
29 | this.userId = userId;
30 | }
31 |
32 | public List getCouponIdList() {
33 | return couponIdList;
34 | }
35 |
36 | public void setCouponIdList(List couponIdList) {
37 | this.couponIdList = couponIdList;
38 | }
39 |
40 | public List getPlaceOrderItemList() {
41 | return placeOrderItemList;
42 | }
43 |
44 | public void setPlaceOrderItemList(List placeOrderItemList) {
45 | this.placeOrderItemList = placeOrderItemList;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/dtos/PlaceOrderItemDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api.dtos;
2 |
3 | import javax.validation.constraints.NotNull;
4 |
5 | /**
6 | * Created by liubin on 2016/5/6.
7 | */
8 | public class PlaceOrderItemDto {
9 |
10 | private int quantity = 0;
11 |
12 | @NotNull(message = "产品ID不能为空")
13 | private Long productId;
14 |
15 | public int getQuantity() {
16 | return quantity;
17 | }
18 |
19 | public void setQuantity(int quantity) {
20 | this.quantity = quantity;
21 | }
22 |
23 | public Long getProductId() {
24 | return productId;
25 | }
26 |
27 | public void setProductId(Long productId) {
28 | this.productId = productId;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/order/api/src/main/java/com/akkafun/order/api/events/OrderCreatePending.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.api.events;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.BaseEvent;
5 | import com.akkafun.base.event.domain.NotifyEvent;
6 | import com.fasterxml.jackson.annotation.JsonCreator;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | /**
12 | * Created by liubin on 2016/5/9.
13 | */
14 | public class OrderCreatePending extends NotifyEvent {
15 |
16 | public static final EventType EVENT_TYPE = EventType.ORDER_CREATE_PENDING;
17 |
18 | @Override
19 | public EventType getType() {
20 | return EVENT_TYPE;
21 | }
22 |
23 | private Long orderId;
24 |
25 | private Long orderNo;
26 |
27 | private Long totalAmount;
28 |
29 | private Long payAmount;
30 |
31 | private Long userId;
32 |
33 | @JsonCreator
34 | public OrderCreatePending(
35 | @JsonProperty("orderId") Long orderId,
36 | @JsonProperty("orderNo") Long orderNo,
37 | @JsonProperty("totalAmount") Long totalAmount,
38 | @JsonProperty("payAmount") Long payAmount,
39 | @JsonProperty("userId") Long userId) {
40 | this.orderId = orderId;
41 | this.orderNo = orderNo;
42 | this.totalAmount = totalAmount;
43 | this.payAmount = payAmount;
44 | this.userId = userId;
45 | }
46 |
47 | public Long getOrderId() {
48 | return orderId;
49 | }
50 |
51 | public Long getOrderNo() {
52 | return orderNo;
53 | }
54 |
55 | public Long getTotalAmount() {
56 | return totalAmount;
57 | }
58 |
59 | public Long getPayAmount() {
60 | return payAmount;
61 | }
62 |
63 | public Long getUserId() {
64 | return userId;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/callback/OrderCreateCallback.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.callback;
2 |
3 | import com.akkafun.account.api.events.AskReduceBalance;
4 | import com.akkafun.base.event.constants.FailureInfo;
5 | import com.akkafun.base.exception.AppBusinessException;
6 | import com.akkafun.common.spring.ApplicationContextHolder;
7 | import com.akkafun.coupon.api.events.AskUseCoupon;
8 | import com.akkafun.order.service.OrderService;
9 | import org.apache.commons.lang3.math.NumberUtils;
10 |
11 | /**
12 | * Created by liubin on 2016/6/16.
13 | */
14 | public class OrderCreateCallback {
15 |
16 | public void onSuccess(AskReduceBalance askReduceBalance, AskUseCoupon askUseCoupon, String orderId) {
17 |
18 | long oId = NumberUtils.toLong(orderId);
19 | if(oId == 0L) {
20 | throw new AppBusinessException("orderId为空: " + orderId);
21 | }
22 |
23 | OrderService orderService = ApplicationContextHolder.context.getBean(OrderService.class);
24 |
25 | orderService.markCreateSuccess(oId);
26 | }
27 |
28 | public void onFailure(AskReduceBalance askReduceBalance, AskUseCoupon askUseCoupon,
29 | String orderId, FailureInfo failureInfo) {
30 |
31 | long oId = NumberUtils.toLong(orderId);
32 | if(oId == 0L) {
33 | throw new AppBusinessException("orderId为空: " + orderId);
34 | }
35 |
36 | OrderService orderService = ApplicationContextHolder.context.getBean(OrderService.class);
37 |
38 | orderService.markCreateFail(oId);
39 |
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/context/OrderApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.context;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.common.event.config.EventConfiguration;
5 | import com.akkafun.common.event.config.InitBindProducer;
6 | import com.akkafun.common.scheduler.config.SchedulerConfiguration;
7 | import com.akkafun.common.spring.BaseConfiguration;
8 | import com.akkafun.common.spring.ServiceClientConfiguration;
9 | import com.akkafun.common.spring.WebApplication;
10 | import org.springframework.boot.SpringApplication;
11 | import org.springframework.boot.autoconfigure.SpringBootApplication;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Import;
14 |
15 | /**
16 | * Created by liubin on 2016/3/28.
17 | */
18 | @SpringBootApplication
19 | @Import({BaseConfiguration.class, EventConfiguration.class, SchedulerConfiguration.class,
20 | ServiceClientConfiguration.class, WebApplication.class})
21 | public class OrderApplication {
22 |
23 | public static void main(String[] args) {
24 | SpringApplication.run(OrderApplication.class, args);
25 | }
26 |
27 | @Bean
28 | public InitBindProducer initBindProducer() {
29 |
30 | InitBindProducer initBindProducer = new InitBindProducer();
31 | initBindProducer.addPreInitializeProducers(EventType.ASK_REDUCE_BALANCE);
32 | initBindProducer.addPreInitializeProducers(EventType.ASK_USE_COUPON);
33 | return initBindProducer;
34 | }
35 |
36 |
37 |
38 | }
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/dao/OrderCouponRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.dao;
2 |
3 | import com.akkafun.order.domain.OrderCoupon;
4 | import com.akkafun.order.domain.OrderItem;
5 | import org.springframework.data.repository.PagingAndSortingRepository;
6 |
7 | /**
8 | * Created by liubin on 2016/4/26.
9 | */
10 | public interface OrderCouponRepository extends PagingAndSortingRepository{
11 | }
12 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/dao/OrderItemRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.dao;
2 |
3 | import com.akkafun.order.domain.OrderItem;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public interface OrderItemRepository extends PagingAndSortingRepository{
10 | }
11 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/dao/OrderRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.dao;
2 |
3 | import com.akkafun.order.domain.Order;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public interface OrderRepository extends PagingAndSortingRepository, OrderRepositoryCustom {
10 | }
11 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/dao/OrderRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.dao;
2 |
3 | import com.akkafun.common.dao.AbstractRepository;
4 |
5 | /**
6 | * Created by liubin on 2016/4/26.
7 | */
8 | public interface OrderRepositoryCustom extends AbstractRepository {
9 | }
10 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/dao/OrderRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public class OrderRepositoryImpl implements OrderRepositoryCustom {
10 |
11 | @PersistenceContext
12 | private EntityManager em;
13 |
14 |
15 | @Override
16 | public EntityManager getEm() {
17 | return em;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/domain/OrderCoupon.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.domain;
2 |
3 | import javax.persistence.*;
4 |
5 | /**
6 | * Created by liubin on 2016/3/28.
7 | */
8 | @Entity
9 | @Table(name = "order_coupon")
10 | public class OrderCoupon {
11 |
12 | @Id
13 | @GeneratedValue(strategy = GenerationType.AUTO)
14 | private Long id;
15 |
16 | @Column
17 | private Long couponId;
18 |
19 | @Column
20 | private Long couponAmount;
21 |
22 | @Column
23 | private String couponCode;
24 |
25 | @Column
26 | private Long orderId;
27 |
28 | @ManyToOne(fetch = FetchType.LAZY)
29 | @JoinColumn(name = "orderId", insertable = false, updatable = false)
30 | private Order order;
31 |
32 |
33 | public Long getId() {
34 | return id;
35 | }
36 |
37 | public void setId(Long id) {
38 | this.id = id;
39 | }
40 |
41 | public Long getCouponId() {
42 | return couponId;
43 | }
44 |
45 | public void setCouponId(Long couponId) {
46 | this.couponId = couponId;
47 | }
48 |
49 | public Long getCouponAmount() {
50 | return couponAmount;
51 | }
52 |
53 | public void setCouponAmount(Long couponAmount) {
54 | this.couponAmount = couponAmount;
55 | }
56 |
57 | public String getCouponCode() {
58 | return couponCode;
59 | }
60 |
61 | public void setCouponCode(String couponCode) {
62 | this.couponCode = couponCode;
63 | }
64 |
65 | public Long getOrderId() {
66 | return orderId;
67 | }
68 |
69 | public void setOrderId(Long orderId) {
70 | this.orderId = orderId;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/domain/OrderItem.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.domain;
2 |
3 | import com.akkafun.common.domain.LockableEntity;
4 |
5 | import javax.persistence.*;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @Entity
11 | @Table(name = "order_item")
12 | public class OrderItem extends LockableEntity {
13 |
14 | @Id
15 | @GeneratedValue(strategy = GenerationType.AUTO)
16 | private Long id;
17 |
18 | @Column
19 | private Long productId;
20 |
21 | @Column
22 | private Long orderId;
23 |
24 | @ManyToOne(fetch = FetchType.LAZY)
25 | @JoinColumn(name = "orderId", insertable = false, updatable = false)
26 | private Order order;
27 |
28 | @Column
29 | private Long price;
30 |
31 | @Column
32 | private int quantity;
33 |
34 | public Long getId() {
35 | return id;
36 | }
37 |
38 | public void setId(Long id) {
39 | this.id = id;
40 | }
41 |
42 | public Long getProductId() {
43 | return productId;
44 | }
45 |
46 | public void setProductId(Long productId) {
47 | this.productId = productId;
48 | }
49 |
50 | public Long getOrderId() {
51 | return orderId;
52 | }
53 |
54 | public void setOrderId(Long orderId) {
55 | this.orderId = orderId;
56 | }
57 |
58 | public Long getPrice() {
59 | return price;
60 | }
61 |
62 | public void setPrice(Long price) {
63 | this.price = price;
64 | }
65 |
66 | public int getQuantity() {
67 | return quantity;
68 | }
69 |
70 | public void setQuantity(int quantity) {
71 | this.quantity = quantity;
72 | }
73 |
74 | public Order getOrder() {
75 | return order;
76 | }
77 |
78 | public void setOrder(Order order) {
79 | this.order = order;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/AccountClient.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.account.api.AccountUrl;
4 | import com.akkafun.base.api.BooleanWrapper;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.web.bind.annotation.PathVariable;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 | import org.springframework.web.bind.annotation.RequestParam;
10 |
11 | /**
12 | * Created by liubin on 2016/8/25.
13 | */
14 | @FeignClient(AccountUrl.SERVICE_HOSTNAME)
15 | public interface AccountClient {
16 |
17 | @RequestMapping(method = RequestMethod.GET, value = AccountUrl.CHECK_ENOUGH_BALANCE)
18 | BooleanWrapper checkEnoughBalance(@PathVariable("userId") Long userId, @RequestParam("balance") Long balance);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/AccountGateway.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.base.exception.RemoteCallException;
4 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | /**
11 | * Created by liubin on 2016/7/18.
12 | */
13 | @Service
14 | public class AccountGateway {
15 |
16 | protected Logger logger = LoggerFactory.getLogger(AccountGateway.class);
17 |
18 | @Autowired
19 | AccountClient accountClient;
20 |
21 | @HystrixCommand(ignoreExceptions = RemoteCallException.class)
22 | public boolean isBalanceEnough(Long userId, Long amount) {
23 | return accountClient.checkEnoughBalance(userId, amount).isSuccess();
24 | }
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/CouponClient.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.coupon.api.CouponUrl;
4 | import com.akkafun.coupon.api.dtos.CouponDto;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RequestMethod;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by liubin on 2016/8/25.
14 | */
15 | @FeignClient(CouponUrl.SERVICE_HOSTNAME)
16 | public interface CouponClient {
17 |
18 | @RequestMapping(method = RequestMethod.GET, value = CouponUrl.COUPON_LIST_URL)
19 | List findCoupons(@RequestParam("id") List id);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/CouponGateway.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.base.api.CommonErrorCode;
4 | import com.akkafun.base.exception.AppBusinessException;
5 | import com.akkafun.base.exception.RemoteCallException;
6 | import com.akkafun.coupon.api.constants.CouponState;
7 | import com.akkafun.coupon.api.dtos.CouponDto;
8 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Service;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.stream.Collectors;
17 |
18 | /**
19 | * Created by liubin on 2016/7/18.
20 | */
21 | @Service
22 | public class CouponGateway {
23 |
24 | protected Logger logger = LoggerFactory.getLogger(CouponGateway.class);
25 |
26 | @Autowired
27 | CouponClient couponClient;
28 |
29 | @HystrixCommand(ignoreExceptions = RemoteCallException.class)
30 | public List findCoupons(List couponIds) {
31 |
32 | if(couponIds.isEmpty()) return new ArrayList<>();
33 |
34 | List couponDtoList = couponClient.findCoupons(couponIds);
35 |
36 | if(!couponDtoList.isEmpty()) {
37 |
38 | //过滤出无效的优惠券
39 | List notValidCouponDtoList = couponDtoList.stream()
40 | .filter(couponDto -> !couponDto.getState().equals(CouponState.VALID))
41 | .collect(Collectors.toList());
42 | if (!notValidCouponDtoList.isEmpty()) {
43 | throw new AppBusinessException(CommonErrorCode.NOT_FOUND,
44 | String.format("无效的优惠券信息, 优惠券id: %s",
45 | notValidCouponDtoList.stream().map(CouponDto::getId).collect(Collectors.toList())));
46 | }
47 | }
48 |
49 | return couponDtoList;
50 | }
51 |
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/ProductClient.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.product.api.ProductUrl;
4 | import com.akkafun.product.api.dtos.ProductDto;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RequestMethod;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by liubin on 2016/8/25.
14 | */
15 | @FeignClient(ProductUrl.SERVICE_HOSTNAME)
16 | public interface ProductClient {
17 |
18 | @RequestMapping(method = RequestMethod.GET, value = ProductUrl.PRODUCT_LIST_URL)
19 | List findProducts(@RequestParam("id") List id);
20 |
21 | @RequestMapping(method = RequestMethod.GET, value = ProductUrl.ALL_PRODUCT_LIST_URL)
22 | List findAllProducts();
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/service/gateway/ProductGateway.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.base.exception.RemoteCallException;
4 | import com.akkafun.product.api.ProductUrl;
5 | import com.akkafun.product.api.dtos.ProductDto;
6 | import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Service;
11 | import org.springframework.web.client.RestTemplate;
12 | import org.springframework.web.util.UriComponentsBuilder;
13 |
14 | import java.net.URI;
15 | import java.util.Arrays;
16 | import java.util.List;
17 |
18 | /**
19 | * Created by liubin on 2016/7/18.
20 | */
21 | @Service
22 | public class ProductGateway {
23 |
24 | protected Logger logger = LoggerFactory.getLogger(ProductGateway.class);
25 |
26 | @Autowired
27 | ProductClient productClient;
28 |
29 | @HystrixCommand(ignoreExceptions = RemoteCallException.class)
30 | public List findProducts(List productIds) {
31 |
32 | return productClient.findProducts(productIds);
33 | }
34 |
35 | @HystrixCommand(ignoreExceptions = RemoteCallException.class)
36 | public List findAllProducts() {
37 | List productDtos = productClient.findAllProducts();
38 |
39 | try {
40 | Thread.sleep(2000L);
41 | } catch (InterruptedException e) {
42 | e.printStackTrace();
43 | }
44 |
45 | return productDtos;
46 |
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/utils/OrderUtils.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.utils;
2 |
3 | import com.akkafun.order.api.dtos.OrderDto;
4 | import com.akkafun.order.api.dtos.OrderItemDto;
5 | import com.akkafun.order.domain.Order;
6 |
7 | import java.util.stream.Collectors;
8 |
9 | /**
10 | * Created by liubin on 2016/6/24.
11 | */
12 | public class OrderUtils {
13 |
14 |
15 | public static OrderDto convertToDto(Order order) {
16 |
17 | OrderDto orderDto = new OrderDto();
18 | orderDto.setCreateTime(order.getCreateTime());
19 | orderDto.setId(order.getId());
20 | orderDto.setOrderNo(order.getOrderNo());
21 | orderDto.setPayAmount(order.getPayAmount());
22 | orderDto.setStatus(order.getStatus());
23 | orderDto.setTotalAmount(order.getTotalAmount());
24 | orderDto.setUpdateTime(order.getUpdateTime());
25 | orderDto.setUserId(order.getUserId());
26 | orderDto.setOrderItemList(order.getOrderItemList().stream().map(orderItem -> {
27 | OrderItemDto orderItemDto = new OrderItemDto();
28 | orderItemDto.setId(orderItem.getId());
29 | orderItemDto.setPrice(orderItem.getPrice());
30 | orderItemDto.setProductId(orderItem.getProductId());
31 | orderItemDto.setQuantity(orderItem.getQuantity());
32 | return orderItemDto;
33 | }).collect(Collectors.toList()));
34 |
35 | return orderDto;
36 |
37 |
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/order/core/src/main/java/com/akkafun/order/web/OrderController.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.web;
2 |
3 | import com.akkafun.order.api.dtos.OrderDto;
4 | import com.akkafun.order.api.dtos.PlaceOrderDto;
5 | import com.akkafun.order.domain.Order;
6 | import com.akkafun.order.service.OrderService;
7 | import com.akkafun.order.utils.OrderUtils;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.http.MediaType;
10 | import org.springframework.web.bind.annotation.*;
11 |
12 | import javax.validation.Valid;
13 |
14 | import static com.akkafun.order.api.OrderUrl.ORDER_INFO;
15 | import static com.akkafun.order.api.OrderUrl.PLACE_ORDER;
16 |
17 | /**
18 | * Created by liubin on 2016/3/29.
19 | */
20 | @RestController
21 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
22 | public class OrderController {
23 |
24 | @Autowired
25 | OrderService orderService;
26 |
27 | @RequestMapping(value = PLACE_ORDER, method = RequestMethod.POST)
28 | public OrderDto placeOrder(@Valid @RequestBody PlaceOrderDto placeOrderDto) {
29 |
30 | Order order = orderService.placeOrder(placeOrderDto);
31 |
32 | return OrderUtils.convertToDto(order);
33 | }
34 |
35 | @RequestMapping(value = ORDER_INFO, method = RequestMethod.GET)
36 | public OrderDto orderInfo(@PathVariable("orderId") Long orderId) {
37 |
38 | Order order = orderService.get(orderId);
39 |
40 | return OrderUtils.convertToDto(order);
41 | }
42 |
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/order/core/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: order
4 | cloud:
5 | config:
6 | uri: ${CONFIG_SERVER_URI:http://localhost:8888}
7 | failFast: true
8 | encrypt:
9 | failOnError: true
10 |
--------------------------------------------------------------------------------
/order/core/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/order-service.log
15 |
16 |
17 | logs/order-service-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/order/core/src/test/java/com/akkafun/order/service/OrderServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service;
2 |
3 | import com.akkafun.order.api.dtos.PlaceOrderDto;
4 | import com.akkafun.order.api.dtos.PlaceOrderItemDto;
5 | import com.akkafun.order.domain.Order;
6 | import com.akkafun.order.test.OrderBaseTest;
7 | import com.google.common.collect.Lists;
8 | import org.junit.Ignore;
9 | import org.junit.Test;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 |
12 | /**
13 | * Created by liubin on 2016/5/9.
14 | */
15 | public class OrderServiceTest extends OrderBaseTest {
16 |
17 | @Autowired
18 | OrderService orderService;
19 |
20 | @Test
21 | @Ignore
22 | public void test() {
23 |
24 | PlaceOrderDto placeOrderDto = new PlaceOrderDto();
25 | placeOrderDto.setUserId(1L);
26 | PlaceOrderItemDto placeOrderItemDto1 = new PlaceOrderItemDto();
27 | placeOrderItemDto1.setProductId(1L);
28 | placeOrderItemDto1.setQuantity(1);
29 | PlaceOrderItemDto placeOrderItemDto2 = new PlaceOrderItemDto();
30 | placeOrderItemDto2.setProductId(2L);
31 | placeOrderItemDto2.setQuantity(2);
32 | placeOrderDto.setPlaceOrderItemList(Lists.newArrayList(placeOrderItemDto1, placeOrderItemDto2));
33 |
34 | Order order = orderService.placeOrder(placeOrderDto);
35 | System.out.println(order.getId());
36 |
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/order/core/src/test/java/com/akkafun/order/service/gateway/ProductGatewayTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.service.gateway;
2 |
3 | import com.akkafun.order.test.OrderBaseTest;
4 | import com.akkafun.product.api.dtos.ProductDto;
5 | import org.junit.Ignore;
6 | import org.junit.Test;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 |
9 | import java.util.List;
10 |
11 | import static org.hamcrest.Matchers.is;
12 | import static org.junit.Assert.assertThat;
13 |
14 | /**
15 | * Created by liubin on 2016/5/9.
16 | */
17 | public class ProductGatewayTest extends OrderBaseTest {
18 |
19 | @Autowired
20 | ProductGateway productGateway;
21 |
22 | @Test
23 | @Ignore
24 | public void test() {
25 |
26 | List productDtos = productGateway.findAllProducts();
27 | assertThat(productDtos.isEmpty(), is(false));
28 |
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/order/core/src/test/java/com/akkafun/order/test/OrderBaseControllerTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.test;
2 |
3 | import com.akkafun.common.test.BaseControllerTest;
4 | import org.springframework.boot.test.SpringApplicationConfiguration;
5 |
6 | /**
7 | * Created by liubin on 2016/3/30.
8 | */
9 | @SpringApplicationConfiguration(classes = TestOrderApplication.class)
10 | public abstract class OrderBaseControllerTest extends BaseControllerTest {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/order/core/src/test/java/com/akkafun/order/test/OrderBaseTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.test;
2 |
3 | import com.akkafun.common.test.BaseTest;
4 | import org.springframework.boot.test.SpringApplicationConfiguration;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | @SpringApplicationConfiguration(classes = TestOrderApplication.class)
10 | public abstract class OrderBaseTest extends BaseTest{
11 | }
12 |
--------------------------------------------------------------------------------
/order/core/src/test/java/com/akkafun/order/test/TestOrderApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.order.test;
2 |
3 | import com.akkafun.common.event.config.EventConfiguration;
4 | import com.akkafun.common.spring.BaseConfiguration;
5 | import com.akkafun.common.spring.ServiceClientConfiguration;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 | import org.springframework.context.annotation.Import;
8 |
9 | /**
10 | * Created by liubin on 2016/3/28.
11 | */
12 | @SpringBootApplication
13 | @Import({BaseConfiguration.class, EventConfiguration.class, ServiceClientConfiguration.class})
14 | public class TestOrderApplication {
15 |
16 |
17 | }
--------------------------------------------------------------------------------
/order/docs/order-service.sql:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangjianbinJAVA/mysteam/8b8abba1f0bdab215e638cdb30ad93f9ef267d6a/order/docs/order-service.sql
--------------------------------------------------------------------------------
/order/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | order-service
6 |
7 | api
8 | core
9 |
10 | pom
11 |
12 |
13 | com.akkafun.mysteam
14 | base
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/product/api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | product-service-api
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | product-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.akkafun.mysteam
19 | apiutils
20 | ${project.version}
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/product/api/src/main/java/com/akkafun/product/api/ProductUrl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.product.api;
2 |
3 | /**
4 | * Created by liubin on 2016/5/6.
5 | */
6 | public interface ProductUrl {
7 |
8 | String SERVICE_NAME = "PRODUCT";
9 |
10 | String SERVICE_HOSTNAME = "http://PRODUCT";
11 |
12 | String ALL_PRODUCT_LIST_URL = "/products/all";
13 |
14 | String PRODUCT_LIST_URL = "/products";
15 |
16 | static String buildUrl(String url) {
17 | return SERVICE_HOSTNAME + url;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/product/api/src/main/java/com/akkafun/product/api/dtos/ProductDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.product.api.dtos;
2 |
3 | /**
4 | * Created by liubin on 2016/5/16.
5 | */
6 | public class ProductDto {
7 |
8 | private Long id;
9 |
10 | private String name;
11 |
12 | private String description;
13 |
14 | private Long price;
15 |
16 | private String category;
17 |
18 |
19 | public Long getId() {
20 | return id;
21 | }
22 |
23 | public void setId(Long id) {
24 | this.id = id;
25 | }
26 |
27 | public String getName() {
28 | return name;
29 | }
30 |
31 | public void setName(String name) {
32 | this.name = name;
33 | }
34 |
35 | public String getDescription() {
36 | return description;
37 | }
38 |
39 | public void setDescription(String description) {
40 | this.description = description;
41 | }
42 |
43 | public Long getPrice() {
44 | return price;
45 | }
46 |
47 | public void setPrice(Long price) {
48 | this.price = price;
49 | }
50 |
51 | public String getCategory() {
52 | return category;
53 | }
54 |
55 | public void setCategory(String category) {
56 | this.category = category;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/product/core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | product-service-core
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | product-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 | com.akkafun.product.context.ProductApplication
17 |
18 |
19 |
20 |
21 |
22 | mysql
23 | mysql-connector-java
24 | runtime
25 |
26 |
27 |
28 | com.akkafun.mysteam
29 | common
30 | ${project.version}
31 |
32 |
33 |
34 | com.akkafun.mysteam
35 | common
36 | ${project.version}
37 | test-jar
38 | test
39 |
40 |
41 |
42 | com.akkafun.mysteam
43 | product-service-api
44 | ${project.version}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-maven-plugin
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/product/core/src/main/java/com/akkafun/product/context/ProductApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.product.context;
2 |
3 | import com.akkafun.common.event.config.EventConfiguration;
4 | import com.akkafun.common.scheduler.config.SchedulerConfiguration;
5 | import com.akkafun.common.spring.BaseConfiguration;
6 | import com.akkafun.common.spring.ServiceClientConfiguration;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.annotation.Import;
10 |
11 | /**
12 | * Created by liubin on 2016/3/28.
13 | */
14 | @SpringBootApplication
15 | @Import({BaseConfiguration.class, EventConfiguration.class, SchedulerConfiguration.class, ServiceClientConfiguration.class})
16 | public class ProductApplication {
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(ProductApplication.class, args);
20 | }
21 |
22 |
23 | }
--------------------------------------------------------------------------------
/product/core/src/main/java/com/akkafun/product/dao/ProductRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.product.dao;
2 |
3 | import com.akkafun.product.domain.Product;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | /**
7 | * Created by liubin on 2016/4/26.
8 | */
9 | public interface ProductRepository extends PagingAndSortingRepository{
10 | }
11 |
--------------------------------------------------------------------------------
/product/core/src/main/java/com/akkafun/product/domain/Product.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.product.domain;
2 |
3 | import javax.persistence.*;
4 |
5 | /**
6 | * Created by liubin on 2016/3/28.
7 | */
8 | @Entity
9 | @Table(name = "product")
10 | public class Product {
11 |
12 | @Id
13 | @GeneratedValue(strategy = GenerationType.AUTO)
14 | private Long id;
15 |
16 | @Column
17 | private String name;
18 |
19 | @Column
20 | private String description;
21 |
22 | @Column
23 | private Long price;
24 |
25 | @Column
26 | private String category;
27 |
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 getName() {
38 | return name;
39 | }
40 |
41 | public void setName(String name) {
42 | this.name = name;
43 | }
44 |
45 | public String getDescription() {
46 | return description;
47 | }
48 |
49 | public void setDescription(String description) {
50 | this.description = description;
51 | }
52 |
53 | public Long getPrice() {
54 | return price;
55 | }
56 |
57 | public void setPrice(Long price) {
58 | this.price = price;
59 | }
60 |
61 | public String getCategory() {
62 | return category;
63 | }
64 |
65 | public void setCategory(String category) {
66 | this.category = category;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/product/core/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: product
4 | cloud:
5 | config:
6 | uri: ${CONFIG_SERVER_URI:http://localhost:8888}
7 | failFast: true
8 | encrypt:
9 | failOnError: true
10 |
--------------------------------------------------------------------------------
/product/core/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/product-service.log
15 |
16 |
17 | logs/product-service-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/product/docs/init-product.sql:
--------------------------------------------------------------------------------
1 | use product_service;
2 |
3 | insert into product values(null, 'The Witcher 3: Wild Hunt', 'The Witcher is a story-driven, next-generation open world role-playing game, set in a visually stunning fantasy universe, full of meaningful choices and impactful consequences. In The Witcher, you play as Geralt of Rivia, a monster hunter tasked with finding a child from an ancient prophecy', 100, 'RPG');
4 | insert into product values(null, 'Resident Evil Revelations 2', 'RE Revelations 2 continues the series acclaimed essential survival horror experience, while uncovering startling truths', 200, 'Scariest Game');
5 | insert into product values(null, 'attack heros', 'attack heros', 300, 'RPG');
6 | insert into product values(null, 'game4', 'game4', 0, 'RPG');
--------------------------------------------------------------------------------
/product/docs/product-service.sql:
--------------------------------------------------------------------------------
1 | /*==============================================================*/
2 | /* DBMS name: MySQL 5.0 */
3 | /* Created on: 2016/5/16 14:30:29 */
4 | /*==============================================================*/
5 |
6 |
7 | drop table if exists product;
8 |
9 | /*==============================================================*/
10 | /* Table: product */
11 | /*==============================================================*/
12 | create table product
13 | (
14 | id bigint unsigned not null auto_increment,
15 | name national varchar(255) not null,
16 | description text,
17 | price bigint,
18 | category varchar(32),
19 | primary key (id)
20 | );
21 |
22 |
--------------------------------------------------------------------------------
/product/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | product-service
6 |
7 | api
8 | core
9 |
10 | pom
11 |
12 |
13 | com.akkafun.mysteam
14 | base
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/turbine/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | turbine
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | base
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 | com.akkafun.turbine.TurbineApplication
16 |
17 |
18 |
19 |
20 |
21 | org.springframework.cloud
22 | spring-cloud-starter-hystrix
23 |
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-starter-hystrix-dashboard
28 |
29 |
30 |
31 | org.springframework.cloud
32 | spring-cloud-starter-turbine
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-maven-plugin
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/turbine/src/main/java/com/akkafun/turbine/TurbineApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.turbine;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
7 | import org.springframework.cloud.netflix.turbine.EnableTurbine;
8 |
9 | @SpringBootApplication
10 | @EnableDiscoveryClient
11 | @EnableTurbine
12 | @EnableHystrixDashboard
13 | public class TurbineApplication {
14 |
15 | public static void main(String[] args) {
16 | SpringApplication.run(TurbineApplication.class, args);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/turbine/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 7777
3 |
4 | spring:
5 | application:
6 | name: turbine
7 |
8 | logging:
9 | level:
10 | org.springframework.cloud: 'INFO'
11 |
12 | turbine:
13 | aggregator:
14 | clusterConfig: USER,ACCOUNT,COUPON,PRODUCT,ORDER
15 | appConfig: user,account,coupon,product,order
16 | instanceUrlSuffix: /hystrix.stream
17 |
18 | # Discovery Server Access
19 | eureka:
20 | instance:
21 | # hostname: localhost
22 | preferIpAddress: true
23 |
24 | client:
25 | serviceUrl:
26 | defaultZone: http://localhost:1111/eureka/
27 |
28 |
--------------------------------------------------------------------------------
/user/api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | user-service-api
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | user-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.akkafun.mysteam
19 | apiutils
20 | ${project.version}
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/UserErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api;
2 |
3 | import com.akkafun.base.api.ErrorCode;
4 |
5 | /**
6 | * Created by liubin on 2016/5/3.
7 | */
8 | public enum UserErrorCode implements ErrorCode {
9 |
10 | UsernameExist(409, "用户名已存在"),
11 | PhoneExist(409, "手机已存在"),
12 | EmailExist(409, "邮箱已存在");
13 |
14 | private int status;
15 |
16 | private String message;
17 |
18 | UserErrorCode(int status, String message) {
19 | this.status = status;
20 | this.message = message;
21 | }
22 |
23 |
24 | @Override
25 | public String getCode() {
26 | return this.name();
27 | }
28 |
29 | @Override
30 | public int getStatus() {
31 | return status;
32 | }
33 |
34 | @Override
35 | public String getMessage() {
36 | return message;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/UserUrl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api;
2 |
3 | /**
4 | * Created by liubin on 2016/3/30.
5 | */
6 | public interface UserUrl {
7 |
8 | String SERVICE_NAME = "USER";
9 |
10 | String SERVICE_HOSTNAME = "http://USER";
11 |
12 | String USER_REGISTER_URL = "/users/register";
13 |
14 | static String buildUrl(String url) {
15 | return SERVICE_HOSTNAME + url;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/dtos/RegisterDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api.dtos;
2 |
3 | import com.akkafun.user.api.utils.RegExpUtils;
4 | import org.hibernate.validator.constraints.NotBlank;
5 |
6 | import javax.validation.constraints.Pattern;
7 | import javax.validation.constraints.Size;
8 |
9 | /**
10 | * Created by liubin on 2016/3/29.
11 | */
12 | public class RegisterDto {
13 |
14 | @NotBlank(message = "用户名不能为空")
15 | @Pattern(regexp = RegExpUtils.USERNAME_REG_EXP, message = "用户名请输入2-20位,可由中文、英文或数字组成")
16 | private String username;
17 |
18 | @NotBlank(message = "密码不能为空")
19 | @Size(min = 4, max = 20, message = "密码长度需要为4-20位")
20 | private String password;
21 |
22 |
23 | public String getUsername() {
24 | return username;
25 | }
26 |
27 | public void setUsername(String username) {
28 | this.username = username;
29 | }
30 |
31 | public String getPassword() {
32 | return password;
33 | }
34 |
35 | public void setPassword(String password) {
36 | this.password = password;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/dtos/UserDto.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api.dtos;
2 |
3 | /**
4 | * Created by liubin on 2016/3/29.
5 | */
6 | public class UserDto {
7 |
8 | private Long id;
9 |
10 | private String username;
11 |
12 | public Long getId() {
13 | return id;
14 | }
15 |
16 | public void setId(Long id) {
17 | this.id = id;
18 | }
19 |
20 | public String getUsername() {
21 | return username;
22 | }
23 |
24 | public void setUsername(String username) {
25 | this.username = username;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/events/UserCreated.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api.events;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.base.event.domain.BaseEvent;
5 | import com.akkafun.base.event.domain.NotifyEvent;
6 | import com.fasterxml.jackson.annotation.JsonCreator;
7 | import com.fasterxml.jackson.annotation.JsonProperty;
8 |
9 | import java.time.LocalDateTime;
10 |
11 | /**
12 | * Created by liubin on 2016/4/8.
13 | */
14 | public class UserCreated extends NotifyEvent {
15 |
16 | public static final EventType EVENT_TYPE = EventType.USER_CREATED;
17 |
18 | @Override
19 | public EventType getType() {
20 | return EVENT_TYPE;
21 | }
22 |
23 | private Long userId;
24 |
25 | private String username;
26 |
27 | private LocalDateTime registerTime;
28 |
29 | @JsonCreator
30 | public UserCreated(
31 | @JsonProperty("userId") Long userId,
32 | @JsonProperty("username") String username,
33 | @JsonProperty("registerTime") LocalDateTime registerTime) {
34 | this.userId = userId;
35 | this.username = username;
36 | this.registerTime = registerTime;
37 | }
38 |
39 | public Long getUserId() {
40 | return userId;
41 | }
42 |
43 | public String getUsername() {
44 | return username;
45 | }
46 |
47 | public LocalDateTime getRegisterTime() {
48 | return registerTime;
49 | }
50 |
51 | @Override
52 | public String toString() {
53 | return "UserCreated{" +
54 | "userId=" + userId +
55 | ", username='" + username + '\'' +
56 | ", registerTime=" + registerTime +
57 | "} " + super.toString();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/user/api/src/main/java/com/akkafun/user/api/utils/RegExpUtils.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.api.utils;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | public class RegExpUtils {
6 |
7 | public static final String USERNAME_REG_EXP = "^[A-Za-z0-9_\\-\\u4e00-\\u9fa5]{2,20}$";
8 | private static final Pattern USERNAME_PATTERN = Pattern.compile(USERNAME_REG_EXP);
9 |
10 | public static final String PHONE_REG_EXP = "^[1][\\d]{10}";
11 | private static final Pattern PHONE_PATTERN = Pattern.compile(PHONE_REG_EXP);
12 |
13 | public static final String EMAIL_REG_EXP = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
14 | private static Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REG_EXP);
15 |
16 |
17 | public static boolean isPhone(String str) {
18 | return str != null && PHONE_PATTERN.matcher(str).matches();
19 |
20 | }
21 |
22 | public static boolean isEmail(String str) {
23 | return str != null && EMAIL_PATTERN.matcher(str).matches();
24 |
25 | }
26 |
27 | public static boolean isUsername(String str) {
28 | return str != null && USERNAME_PATTERN.matcher(str).matches();
29 |
30 | }
31 |
32 |
33 | public static void main(String[] args) {
34 | String phone1 = "18622223333";
35 | String email1 = "123@1.com";
36 | String email2 = "123@.com";
37 |
38 | System.out.println(isPhone(phone1));
39 | System.out.println(isEmail(email1));
40 | System.out.println(isEmail(email2));
41 |
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/user/core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | 4.0.0
5 | user-service-core
6 | jar
7 |
8 |
9 | com.akkafun.mysteam
10 | user-service
11 | 1.0-SNAPSHOT
12 |
13 |
14 |
15 |
16 | com.akkafun.user.context.UserApplication
17 |
18 |
19 |
20 |
21 |
22 | mysql
23 | mysql-connector-java
24 | runtime
25 |
26 |
27 |
28 | com.akkafun.mysteam
29 | common
30 | ${project.version}
31 |
32 |
33 |
34 | com.akkafun.mysteam
35 | common
36 | ${project.version}
37 | test-jar
38 | test
39 |
40 |
41 |
42 | com.akkafun.mysteam
43 | user-service-api
44 | ${project.version}
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-maven-plugin
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/context/UserApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.context;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.common.event.config.EventConfiguration;
5 | import com.akkafun.common.event.config.InitBindProducer;
6 | import com.akkafun.common.scheduler.config.SchedulerConfiguration;
7 | import com.akkafun.common.spring.BaseConfiguration;
8 | import com.akkafun.common.spring.ServiceClientConfiguration;
9 | import com.akkafun.common.spring.WebApplication;
10 | import org.springframework.boot.SpringApplication;
11 | import org.springframework.boot.autoconfigure.SpringBootApplication;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.context.annotation.Import;
14 |
15 | /**
16 | * Created by liubin on 2016/3/28.
17 | */
18 | @SpringBootApplication
19 | @Import({BaseConfiguration.class, EventConfiguration.class, SchedulerConfiguration.class,
20 | ServiceClientConfiguration.class, WebApplication.class})
21 | public class UserApplication {
22 |
23 | public static void main(String[] args) {
24 | SpringApplication.run(UserApplication.class, args);
25 | }
26 |
27 | @Bean
28 | public InitBindProducer initBindProducer() {
29 |
30 | InitBindProducer initBindProducer = new InitBindProducer();
31 | initBindProducer.addPreInitializeProducers(EventType.USER_CREATED);
32 | return initBindProducer;
33 | }
34 |
35 |
36 | }
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/dao/UserRepository.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.dao;
2 |
3 | import com.akkafun.user.domain.User;
4 | import org.springframework.data.repository.PagingAndSortingRepository;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | public interface UserRepository extends PagingAndSortingRepository, UserRepositoryCustom {
10 |
11 |
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/dao/UserRepositoryCustom.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.dao;
2 |
3 |
4 | import com.akkafun.common.dao.AbstractRepository;
5 |
6 | import java.util.Optional;
7 |
8 | /**
9 | * Created by liubin on 2016/3/29.
10 | */
11 | public interface UserRepositoryCustom extends AbstractRepository {
12 |
13 | /**
14 | * 用户名是否存在
15 | * @param username
16 | * @param userId
17 | * @return
18 | */
19 | boolean isUsernameExist(String username, Optional userId);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/dao/UserRepositoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.dao;
2 |
3 | import javax.persistence.EntityManager;
4 | import javax.persistence.PersistenceContext;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.Optional;
9 |
10 | /**
11 | * Created by liubin on 2016/3/29.
12 | */
13 | public class UserRepositoryImpl implements UserRepositoryCustom {
14 |
15 | @PersistenceContext
16 | private EntityManager em;
17 |
18 |
19 | @Override
20 | public boolean isUsernameExist(String username, Optional userId) {
21 |
22 | String hql = "select u.id from User u where u.username = :username";
23 | Map params = new HashMap<>();
24 | params.put("username", username);
25 | if(userId.isPresent()) {
26 | hql += " and u.userId != :userId ";
27 | params.put("userId", userId);
28 | }
29 | List results = query(hql, params);
30 | return !results.isEmpty();
31 | }
32 |
33 |
34 | @Override
35 | public EntityManager getEm() {
36 | return em;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/domain/User.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.domain;
2 |
3 | import com.akkafun.common.domain.VersionEntity;
4 |
5 | import javax.persistence.*;
6 |
7 | /**
8 | * Created by liubin on 2016/3/28.
9 | */
10 | @Entity
11 | @Table(name = "user")
12 | public class User extends VersionEntity {
13 |
14 | @Id
15 | @GeneratedValue(strategy = GenerationType.AUTO)
16 | private Long id;
17 |
18 | @Column
19 | private String username;
20 |
21 | @Column
22 | private String password;
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 getUsername() {
33 | return username;
34 | }
35 |
36 | public void setUsername(String username) {
37 | this.username = username;
38 | }
39 |
40 | public String getPassword() {
41 | return password;
42 | }
43 |
44 | public void setPassword(String password) {
45 | this.password = password;
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/user/core/src/main/java/com/akkafun/user/web/UserController.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.web;
2 |
3 | import com.akkafun.user.api.dtos.RegisterDto;
4 | import com.akkafun.user.api.dtos.UserDto;
5 | import com.akkafun.user.domain.User;
6 | import com.akkafun.user.service.UserService;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.MediaType;
9 | import org.springframework.web.bind.annotation.RequestBody;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 | import org.springframework.web.bind.annotation.RestController;
13 |
14 | import javax.validation.Valid;
15 |
16 | import static com.akkafun.user.api.UserUrl.USER_REGISTER_URL;
17 |
18 | /**
19 | * Created by liubin on 2016/3/29.
20 | */
21 | @RestController
22 | @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
23 | public class UserController {
24 |
25 | @Autowired
26 | UserService userService;
27 |
28 | @RequestMapping(value = USER_REGISTER_URL, method = RequestMethod.POST)
29 | public UserDto register(@Valid @RequestBody RegisterDto registerDto) {
30 |
31 | User user = userService.register(registerDto);
32 | UserDto userDto = new UserDto();
33 | userDto.setId(user.getId());
34 | userDto.setUsername(user.getUsername());
35 |
36 | return userDto;
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/user/core/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: user
4 | cloud:
5 | config:
6 | uri: ${CONFIG_SERVER_URI:http://localhost:8888}
7 | failFast: true
8 | encrypt:
9 | failOnError: true
10 |
--------------------------------------------------------------------------------
/user/core/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 | logs/user-service.log
15 |
16 |
17 | logs/user-service-log-%d{yyyy-MM-dd}.gz
18 |
19 | 30
20 |
21 |
22 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
23 |
24 |
25 |
26 |
27 |
28 | %date{yyyy-MM-dd HH:mm:ss} ${PID}: %-5level %logger{0} - %msg%n
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/common/event/load/FakeAskCouponUse.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.load;
2 |
3 | import org.apache.commons.lang.RandomStringUtils;
4 |
5 | /**
6 | * Created by liubin on 2016/5/30.
7 | */
8 | public class FakeAskCouponUse extends FakeAskEvent {
9 |
10 | private String id;
11 |
12 | public FakeAskCouponUse() {
13 | this.id = RandomStringUtils.randomAlphanumeric(8);
14 | }
15 |
16 | public String getId() {
17 | return id;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return "FakeAskCouponUse{" +
23 | "id='" + id + '\'' +
24 | "} " + super.toString();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/common/event/load/FakeAskDeductBalance.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.load;
2 |
3 | import org.apache.commons.lang.RandomStringUtils;
4 |
5 | /**
6 | * Created by liubin on 2016/5/30.
7 | */
8 | public class FakeAskDeductBalance extends FakeAskEvent {
9 |
10 | private String id;
11 |
12 | public FakeAskDeductBalance() {
13 | this.id = RandomStringUtils.randomAlphanumeric(8);
14 | }
15 |
16 | public String getId() {
17 | return id;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return "FakeAskDeductBalance{" +
23 | "id='" + id + '\'' +
24 | "} " + super.toString();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/common/event/load/FakeAskEvent.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.load;
2 |
3 | /**
4 | * Created by liubin on 2016/5/30.
5 | */
6 | public class FakeAskEvent {
7 | }
8 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/common/event/load/FakeEventBus.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.load;
2 |
3 | /**
4 | * Created by liubin on 2016/5/30.
5 | */
6 | public class FakeEventBus {
7 |
8 | public void askUnited(FakeUnitedAskEventCallback callback, FakeAskEvent firstAskEvent, FakeAskEvent secondAskEvent,
9 | FakeAskEvent... remainAskEvents) {
10 | System.out.println(callback.getClass());
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/common/event/load/FakeUnitedAskEventCallback.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.event.load;
2 |
3 | /**
4 | * Created by liubin on 2016/5/30.
5 | */
6 | public interface FakeUnitedAskEventCallback {
7 |
8 | void onSuccess(FakeAskEvent[] askEvents);
9 |
10 | void onFailure(FakeAskEvent[] askEvents);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/user/test/TestUserApplication.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.test;
2 |
3 | import com.akkafun.base.event.constants.EventType;
4 | import com.akkafun.common.event.config.EventConfiguration;
5 | import com.akkafun.common.event.service.EventActivator;
6 | import com.akkafun.common.spring.BaseConfiguration;
7 | import com.akkafun.common.spring.WebApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Import;
11 |
12 | /**
13 | * Created by liubin on 2016/3/28.
14 | */
15 | @SpringBootApplication
16 | @Import({BaseConfiguration.class, EventConfiguration.class})
17 | public class TestUserApplication {
18 |
19 |
20 | /**
21 | * 测试EventBus.sendUnpublishedEvent中调用sendMessage抛出异常会不会导致整个事务回滚
22 | * @param eventActivator
23 | * @return
24 | */
25 | @Bean
26 | public EventActivator testEventActivator(EventActivator eventActivator) {
27 |
28 | return new EventActivator() {
29 | @Override
30 | public boolean sendMessage(String message, String destination) {
31 | //当遇到TEST_EVENT_SECOND事件时, 抛出异常
32 | if(destination.equals(EventType.NOTIFY_SECOND_TEST_EVENT.toString())) {
33 | throw new RuntimeException("我是异常");
34 | }
35 | return eventActivator.sendMessage(message, destination);
36 | }
37 |
38 | @Override
39 | public void receiveMessage(Object payload) {
40 | eventActivator.receiveMessage(payload);
41 | }
42 | };
43 |
44 |
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/user/test/UserBaseControllerTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.test;
2 |
3 | import com.akkafun.common.test.BaseControllerTest;
4 | import org.springframework.boot.test.SpringApplicationConfiguration;
5 |
6 | /**
7 | * Created by liubin on 2016/3/30.
8 | */
9 | @SpringApplicationConfiguration(classes = TestUserApplication.class)
10 | public abstract class UserBaseControllerTest extends BaseControllerTest {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/user/core/src/test/java/com/akkafun/user/test/UserBaseTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.user.test;
2 |
3 | import com.akkafun.common.test.BaseTest;
4 | import org.springframework.boot.test.SpringApplicationConfiguration;
5 |
6 | /**
7 | * Created by liubin on 2016/3/29.
8 | */
9 | @SpringApplicationConfiguration(classes = TestUserApplication.class)
10 | public abstract class UserBaseTest extends BaseTest{
11 | }
12 |
--------------------------------------------------------------------------------
/user/docs/user-service.sql:
--------------------------------------------------------------------------------
1 | /*==============================================================*/
2 | /* DBMS name: MySQL 5.0 */
3 | /* Created on: 2016/8/10 11:33:27 */
4 | /*==============================================================*/
5 |
6 |
7 | drop table if exists user;
8 |
9 | /*==============================================================*/
10 | /* Table: user */
11 | /*==============================================================*/
12 | create table user
13 | (
14 | id bigint unsigned not null auto_increment,
15 | username varchar(100) not null,
16 | password varchar(255) not null,
17 | createTime datetime,
18 | updateTime datetime,
19 | optlock int default 0,
20 | primary key (id)
21 | );
22 |
23 |
--------------------------------------------------------------------------------
/user/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | user-service
6 |
7 | api
8 | core
9 |
10 | pom
11 |
12 |
13 | com.akkafun.mysteam
14 | base
15 | 1.0-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/utils/src/main/java/com/akkafun/common/utils/CustomPreconditions.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.utils;
2 |
3 | import com.akkafun.base.Constants;
4 | import com.akkafun.base.api.CommonErrorCode;
5 | import com.akkafun.base.exception.AppBusinessException;
6 |
7 | /**
8 | * Created by liubin on 2016/6/23.
9 | */
10 | public class CustomPreconditions {
11 |
12 | public static void assertNotGreaterThanMaxQueryBatchSize(int size) {
13 | if(size > Constants.MAX_BATCH_QUERY_SIZE) throw new AppBusinessException(CommonErrorCode.BAD_REQUEST,
14 | "一次查询的id数量不能超过" + Constants.MAX_BATCH_QUERY_SIZE);
15 |
16 | }
17 |
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/utils/src/main/java/com/akkafun/common/utils/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.utils;
2 |
3 | import java.io.UnsupportedEncodingException;
4 |
5 | /**
6 | * Created by liubin on 2016/8/5.
7 | */
8 | public class StringUtils extends org.apache.commons.lang3.StringUtils {
9 |
10 |
11 | /**
12 | * 截取字符串, 中文按2个字节长度计算
13 | * @param str
14 | * @param n
15 | * @return
16 | */
17 | public static String abbreviate4Unicode(String str, int n) {
18 | if (str == null)return "";
19 | if (n <= 0) return str;
20 | try {
21 | return cutString(str, n);
22 | } catch (UnsupportedEncodingException e) {
23 | throw new RuntimeException(e);
24 | }
25 | }
26 |
27 |
28 | private static String cutString(String s, int length) throws UnsupportedEncodingException {
29 |
30 | byte[] bytes = s.getBytes("Unicode");
31 | int n = 0; // 表示当前的字节数
32 | int i = 2; // 要截取的字节数,从第3个字节开始
33 | for (; i < bytes.length && n < length; i++){
34 | // 奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节
35 | if (i % 2 == 1){
36 | n++; // 在UCS2第二个字节时n加1
37 | }
38 | else{
39 | // 当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节
40 | if (bytes[i] != 0){
41 | n++;
42 | }
43 | }
44 | }
45 | // 如果i为奇数时,处理成偶数
46 | if (i % 2 == 1){
47 | // 该UCS2字符是汉字时,去掉这个截一半的汉字
48 | if (bytes[i - 1] != 0){
49 | i = i - 1;
50 | }
51 | // 该UCS2字符是字母或数字,则保留该字符
52 | else{
53 | i = i + 1;
54 | }
55 | }
56 |
57 | String result = new String(bytes, 0, i, "Unicode");
58 |
59 | if(i < bytes.length && isNotBlank(result)) {
60 | result = result + "...";
61 | }
62 |
63 | return result;
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/utils/src/main/java/com/akkafun/common/utils/UpdateByIdFunction.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.utils;
2 |
3 | /**
4 | * Created by liubin on 2016/4/13.
5 | */
6 | public interface UpdateByIdFunction {
7 |
8 | int execute(Long[] ids, Object... args);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/utils/src/main/java/com/akkafun/common/utils/ZkUtils.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.utils;
2 |
3 | /**
4 | * Created by liubin on 2016/4/20.
5 | */
6 | public class ZkUtils {
7 |
8 | public static final String ZK_ROOT = "/mysteam";
9 |
10 | public static String createZkSchedulerLeaderPath(String applicationName) {
11 | return String.format("%s/%s/schedulers", ZK_ROOT, applicationName);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/utils/src/test/java/com/akkafun/common/utils/StringUtilsTest.java:
--------------------------------------------------------------------------------
1 | package com.akkafun.common.utils;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.hamcrest.Matchers.is;
6 | import static org.junit.Assert.assertThat;
7 |
8 | /**
9 | * Created by liubin on 2016/8/5.
10 | */
11 | public class StringUtilsTest {
12 |
13 | @Test
14 | public void test() {
15 |
16 | assertResult("你叫什么名123字啊", 1, "");
17 | assertResult("你叫什么名123字啊", 2, "你...");
18 | assertResult("你叫什么名123字啊", 3, "你...");
19 | assertResult("你叫什么名123字啊", 4, "你叫...");
20 | assertResult("你叫什么名123字啊", 5, "你叫...");
21 | assertResult("你叫什么名123字啊", 16, "你叫什么名123字...");
22 | assertResult("你叫什么名123字啊", 17, "你叫什么名123字啊");
23 | assertResult("你叫什么名123字啊", 18, "你叫什么名123字啊");
24 | assertResult("你叫什么名123字啊", 88, "你叫什么名123字啊");
25 |
26 | assertResult("abcdef", 1, "a...");
27 | assertResult("abcdef", 2, "ab...");
28 | assertResult("abcdef", 5, "abcde...");
29 | assertResult("abcdef", 6, "abcdef");
30 | assertResult("abcdef", 7, "abcdef");
31 |
32 | assertResult("你123叫什么名字啊", 3, "你1...");
33 | assertResult("你123叫什么名字啊", 4, "你12...");
34 | assertResult("你123叫什么名字啊", 5, "你123...");
35 | assertResult("你123叫什么名字啊", 6, "你123...");
36 | assertResult("你123叫什么名字啊", 7, "你123叫...");
37 |
38 | }
39 |
40 |
41 | private static void assertResult(String str, int n, String result) {
42 |
43 | assertThat(StringUtils.abbreviate4Unicode(str, n), is(result));
44 | }
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------