├── README.md
├── account-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── springcss
│ │ └── account
│ │ ├── AccountApplication.java
│ │ ├── controller
│ │ └── AccountController.java
│ │ ├── domain
│ │ └── Account.java
│ │ ├── endpoint
│ │ ├── AccountEndpoint.java
│ │ ├── CustomBuildInfoContributor.java
│ │ ├── CustomerServiceHealthIndicator.java
│ │ └── MySystemEndpoint.java
│ │ ├── message
│ │ ├── AbstractAccountChangedPublisher.java
│ │ ├── AccountChangedPublisher.java
│ │ ├── amqp
│ │ │ ├── RabbitMQAccountChangedPublisher.java
│ │ │ └── RabbitMQMessagingConfig.java
│ │ ├── jms
│ │ │ ├── ActiveMQAccountChangedPublisher.java
│ │ │ └── ActiveMQMessagingConfig.java
│ │ └── kafka
│ │ │ └── KafkaAccountChangedPublisher.java
│ │ ├── repository
│ │ └── AccountRepository.java
│ │ ├── security
│ │ ├── SpringCssSecurityConfig.java
│ │ ├── SpringCssUser.java
│ │ ├── SpringCssUserDetailsService.java
│ │ └── SpringCssUserRepository.java
│ │ └── service
│ │ └── AccountService.java
│ └── resources
│ ├── META-INF
│ └── additional-spring-configuration-metadata.json
│ ├── account.sql
│ ├── application-activemq.yml
│ ├── application-kafka.yml
│ ├── application-rabbitmq.yml
│ ├── application.yml
│ └── bootstrap.yml
├── admin-server
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── springcss
│ │ └── admin
│ │ └── AdminApplication.java
│ └── resources
│ └── application.yml
├── customer-service
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── springcss
│ │ │ └── customer
│ │ │ ├── CustomerApplication.java
│ │ │ ├── client
│ │ │ ├── OrderClient.java
│ │ │ └── OrderMapper.java
│ │ │ ├── controller
│ │ │ ├── CustomerController.java
│ │ │ ├── HealthController.java
│ │ │ └── MessageReceiveController.java
│ │ │ ├── domain
│ │ │ ├── CustomerTicket.java
│ │ │ └── LocalAccount.java
│ │ │ ├── message
│ │ │ ├── AbstractAccountChangedReceiver.java
│ │ │ ├── AccountChangedReceiver.java
│ │ │ ├── amqp
│ │ │ │ ├── RabbitMQAccountChangedReceiver.java
│ │ │ │ └── RabbitMQMessagingConfig.java
│ │ │ ├── jms
│ │ │ │ ├── ActiveMQAccountChangedReceiver.java
│ │ │ │ └── ActiveMQMessagingConfig.java
│ │ │ └── kafka
│ │ │ │ └── KafkaAccountChangedListener.java
│ │ │ ├── metrics
│ │ │ ├── CounterService.java
│ │ │ └── CustomerTicketMetrics.java
│ │ │ ├── repository
│ │ │ ├── CustomerTicketRepository.java
│ │ │ └── LocalAccountRepository.java
│ │ │ └── service
│ │ │ └── CustomerTicketService.java
│ └── resources
│ │ ├── application-activemq.yml
│ │ ├── application-kafka.yml
│ │ ├── application-rabbitmq.yml
│ │ ├── application.yml
│ │ ├── bootstrap.yml
│ │ └── customer.sql
│ └── test
│ ├── java
│ └── com
│ │ └── springcss
│ │ └── customer
│ │ ├── ApplicationContextTests.java
│ │ ├── CustomerControllerTestsWithAutoConfigureMockMvc.java
│ │ ├── CustomerControllerTestsWithMockMvc.java
│ │ ├── CustomerControllerTestsWithTestRestTemplate.java
│ │ ├── CustomerRepositoryTest.java
│ │ ├── CustomerServiceTests.java
│ │ ├── CustomerTicketTests.java
│ │ └── EnvironmentTests.java
│ └── resources
│ └── application.properties
├── message
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── springcss
│ └── message
│ ├── AccountChangedEvent.java
│ ├── AccountChannels.java
│ └── AccountMessage.java
├── order-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── springcss
│ │ └── order
│ │ ├── OrderApplication.java
│ │ ├── controller
│ │ ├── JpaOrderController.java
│ │ └── OrderController.java
│ │ ├── domain
│ │ ├── Goods.java
│ │ ├── JpaGoods.java
│ │ ├── JpaOrder.java
│ │ └── Order.java
│ │ ├── repository
│ │ ├── OrderJdbcRepository.java
│ │ ├── OrderJpaRepository.java
│ │ ├── OrderRawJdbcRepository.java
│ │ ├── OrderRepository.java
│ │ └── jdbctemplate
│ │ │ ├── AbstractJdbcTemplate.java
│ │ │ ├── AbstractJdbcTemplateTest.java
│ │ │ ├── CallbackJdbcTemplate.java
│ │ │ ├── CallbackJdbcTemplateTest.java
│ │ │ ├── OrderJdbcTemplate.java
│ │ │ └── StatementCallback.java
│ │ └── service
│ │ ├── JpaOrderService.java
│ │ └── OrderService.java
│ └── resources
│ ├── application-prod.yml
│ ├── application-test.yml
│ ├── application-uat.yml
│ ├── application.yml
│ ├── bootstrap.yml
│ ├── data.sql
│ └── schema.sql
└── pom.xml
/README.md:
--------------------------------------------------------------------------------
1 | # SpringBoot-jianxiang
--------------------------------------------------------------------------------
/account-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.springcss
8 | account-service
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | Account Service
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 |
23 | com.springcss
24 | message
25 | 0.0.1-SNAPSHOT
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-data-jpa
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-web
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-hateoas
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-actuator
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-starter-data-rest
47 |
48 |
49 |
50 | com.h2database
51 | h2
52 |
53 |
54 |
55 | mysql
56 | mysql-connector-java
57 |
58 |
59 |
60 | org.apache.commons
61 | commons-pool2
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-starter-artemis
67 |
68 |
69 |
70 | org.springframework.boot
71 | spring-boot-starter-amqp
72 |
73 |
74 | org.springframework.kafka
75 | spring-kafka
76 |
77 |
78 |
79 | org.springframework.boot
80 | spring-boot-starter-security
81 |
82 |
83 |
84 | org.springframework.boot
85 | spring-boot-starter-test
86 | test
87 |
88 |
89 |
90 |
91 |
92 |
93 | org.springframework.boot
94 | spring-boot-maven-plugin
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/AccountApplication.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class AccountApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(AccountApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/controller/AccountController.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.controller;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.security.access.prepost.PreAuthorize;
7 | import org.springframework.web.bind.annotation.DeleteMapping;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.PathVariable;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.PutMapping;
12 | import org.springframework.web.bind.annotation.RequestBody;
13 | import org.springframework.web.bind.annotation.RequestMapping;
14 | import org.springframework.web.bind.annotation.RestController;
15 |
16 | import com.springcss.account.domain.Account;
17 | import com.springcss.account.service.AccountService;
18 |
19 | @RestController
20 | @RequestMapping(value = "accounts", produces="application/json")
21 | public class AccountController {
22 |
23 | @Autowired
24 | private AccountService accountService;
25 |
26 | private static final Logger logger = LoggerFactory.getLogger(AccountController.class);
27 |
28 | @GetMapping(value = "/{accountId}")
29 | public Account getAccountById(@PathVariable("accountId") Long accountId) {
30 |
31 | logger.info("Get account by id: {} ", accountId);
32 |
33 | Account account = new Account();
34 | account.setId(1L);
35 | account.setAccountCode("DemoCode");
36 | account.setAccountName("DemoName");
37 |
38 | // Account account = accountService.getAccountById(accountId);
39 | return account;
40 | }
41 |
42 | @GetMapping(value = "accountname/{accountName}")
43 | public Account getAccountByAccountName(@PathVariable("accountName") String accountName) {
44 |
45 | Account account = accountService.getAccountByAccountName(accountName);
46 | return account;
47 | }
48 |
49 | @PostMapping(value = "/")
50 | public void addAccount(@RequestBody Account account) {
51 |
52 | accountService.addAccount(account);
53 | }
54 |
55 | @PutMapping(value = "/")
56 | public void updateAccount(@RequestBody Account account) {
57 |
58 | accountService.updateAccount(account);
59 | }
60 |
61 | @DeleteMapping(value = "/")
62 | public void deleteAccount(@RequestBody Account account) {
63 |
64 | accountService.deleteAccount(account);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/domain/Account.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.domain;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 | import javax.persistence.Table;
7 |
8 | @Entity
9 | @Table(name = "account")
10 | public class Account {
11 | @Id
12 | @GeneratedValue
13 | private Long id;
14 | private String accountCode;
15 | private String accountName;
16 |
17 | public Long getId() {
18 | return id;
19 | }
20 | public void setId(Long id) {
21 | this.id = id;
22 | }
23 | public String getAccountCode() {
24 | return accountCode;
25 | }
26 | public void setAccountCode(String accountCode) {
27 | this.accountCode = accountCode;
28 | }
29 | public String getAccountName() {
30 | return accountName;
31 | }
32 | public void setAccountName(String accountName) {
33 | this.accountName = accountName;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/endpoint/AccountEndpoint.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.endpoint;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
8 | import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
9 | import org.springframework.boot.actuate.endpoint.annotation.Selector;
10 | import org.springframework.context.annotation.Configuration;
11 |
12 | import com.springcss.account.repository.AccountRepository;
13 |
14 | @Configuration
15 | @Endpoint(id = "account", enableByDefault = true)
16 | public class AccountEndpoint {
17 |
18 | @Autowired
19 | private AccountRepository accountRepository;
20 |
21 | @ReadOperation
22 | public Map getMySystemInfo(@Selector String accountName) {
23 | Map result = new HashMap<>();
24 | result.put(accountName, accountRepository.findAccountByAccountName(accountName));
25 | return result;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/endpoint/CustomBuildInfoContributor.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.endpoint;
2 |
3 | import java.util.Collections;
4 | import java.util.Date;
5 |
6 | import org.springframework.boot.actuate.info.Info.Builder;
7 | import org.springframework.boot.actuate.info.InfoContributor;
8 | import org.springframework.stereotype.Component;
9 |
10 | @Component
11 | public class CustomBuildInfoContributor implements InfoContributor {
12 |
13 | @Override
14 | public void contribute(Builder builder) {
15 | builder.withDetail("build",
16 | Collections.singletonMap("timestamp", new Date()));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/endpoint/CustomerServiceHealthIndicator.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.endpoint;
2 |
3 | import java.io.IOException;
4 | import java.net.HttpURLConnection;
5 | import java.net.URL;
6 |
7 | import org.springframework.boot.actuate.health.Health;
8 | import org.springframework.boot.actuate.health.HealthIndicator;
9 | import org.springframework.stereotype.Component;
10 |
11 | @Component
12 | public class CustomerServiceHealthIndicator implements HealthIndicator {
13 |
14 | @Override
15 | public Health health() {
16 | try {
17 | URL url = new URL("http://localhost:8083/health/");
18 | HttpURLConnection conn = (HttpURLConnection) url.openConnection();
19 | int statusCode = conn.getResponseCode();
20 | if (statusCode >= 200 && statusCode < 300) {
21 | return Health.up().build();
22 | } else {
23 | return Health.down().withDetail("HTTP Status Code", statusCode).build();
24 | }
25 | } catch (IOException e) {
26 | return Health.down(e).build();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/endpoint/MySystemEndpoint.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.endpoint;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
7 | import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | @Configuration
11 | @Endpoint(id = "mysystem", enableByDefault = true)
12 | public class MySystemEndpoint {
13 |
14 | @ReadOperation
15 | public Map getMySystemInfo() {
16 | Map result = new HashMap<>();
17 | Map map = System.getenv();
18 | result.put("username", map.get("USERNAME"));
19 | result.put("computername", map.get("COMPUTERNAME"));
20 | return result;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/AbstractAccountChangedPublisher.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message;
2 |
3 | import com.springcss.account.domain.Account;
4 | import com.springcss.message.AccountChangedEvent;
5 | import com.springcss.message.AccountMessage;
6 |
7 | public abstract class AbstractAccountChangedPublisher implements AccountChangedPublisher {
8 |
9 | @Override
10 | public void publishAccountChangedEvent(Account account, String operation) {
11 |
12 | AccountMessage accountMessage = new AccountMessage(account.getId(), account.getAccountCode(), account.getAccountName());
13 | AccountChangedEvent event = new AccountChangedEvent(AccountChangedEvent.class.getTypeName(),
14 | operation.toString(), accountMessage);
15 |
16 | publishEvent(event);
17 | }
18 |
19 | protected abstract void publishEvent(AccountChangedEvent event);
20 | }
21 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/AccountChangedPublisher.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message;
2 |
3 | import com.springcss.account.domain.Account;
4 |
5 | public interface AccountChangedPublisher {
6 |
7 | void publishAccountChangedEvent(Account account, String operation);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/amqp/RabbitMQAccountChangedPublisher.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message.amqp;
2 |
3 | import org.springframework.amqp.AmqpException;
4 | import org.springframework.amqp.core.Message;
5 | import org.springframework.amqp.core.MessagePostProcessor;
6 | import org.springframework.amqp.core.MessageProperties;
7 | import org.springframework.amqp.rabbit.core.RabbitTemplate;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Component;
10 |
11 | import com.springcss.account.message.AbstractAccountChangedPublisher;
12 | import com.springcss.message.AccountChangedEvent;
13 | import com.springcss.message.AccountChannels;
14 |
15 | @Component("rabbitMQAccountChangedPublisher")
16 | public class RabbitMQAccountChangedPublisher extends AbstractAccountChangedPublisher {
17 |
18 | @Autowired
19 | private RabbitTemplate rabbitTemplate;
20 |
21 | @Override
22 | protected void publishEvent(AccountChangedEvent event) {
23 | rabbitTemplate.convertAndSend(AccountChannels.SPRINGCSS_ACCOUNT_QUEUE, event, new MessagePostProcessor() {
24 | @Override
25 | public Message postProcessMessage(Message message) throws AmqpException {
26 | MessageProperties props = message.getMessageProperties();
27 | props.setHeader("EVENT_SYSTEM", "SpringCSS");
28 | return message;
29 | }
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/amqp/RabbitMQMessagingConfig.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message.amqp;
2 |
3 | import org.springframework.amqp.core.Binding;
4 | import org.springframework.amqp.core.BindingBuilder;
5 | import org.springframework.amqp.core.DirectExchange;
6 | import org.springframework.amqp.core.Queue;
7 | import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 |
11 | import com.springcss.message.AccountChannels;
12 |
13 | @Configuration
14 | public class RabbitMQMessagingConfig {
15 |
16 | public static final String SPRINGCSS_ACCOUNT_DIRECT_EXCHANGE = "springcss.account.exchange";
17 | public static final String SPRINGCSS_ACCOUNT_ROUTING = "springcss.account.routing";
18 |
19 | @Bean
20 | public Queue SpringCssDirectQueue() {
21 | return new Queue(AccountChannels.SPRINGCSS_ACCOUNT_QUEUE, true);
22 | }
23 |
24 | @Bean
25 | public DirectExchange SpringCssDirectExchange() {
26 | return new DirectExchange(SPRINGCSS_ACCOUNT_DIRECT_EXCHANGE, true, false);
27 | }
28 |
29 | @Bean
30 | public Binding bindingDirect() {
31 | return BindingBuilder.bind(SpringCssDirectQueue()).to(SpringCssDirectExchange())
32 | .with(SPRINGCSS_ACCOUNT_ROUTING);
33 | }
34 |
35 | @Bean
36 | public Jackson2JsonMessageConverter rabbitMQMessageConverter() {
37 | return new Jackson2JsonMessageConverter();
38 | }
39 | }
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/jms/ActiveMQAccountChangedPublisher.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message.jms;
2 |
3 | import javax.jms.JMSException;
4 | import javax.jms.Message;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.jms.core.JmsTemplate;
8 | import org.springframework.stereotype.Component;
9 |
10 | import com.springcss.account.message.AbstractAccountChangedPublisher;
11 | import com.springcss.message.AccountChangedEvent;
12 | import com.springcss.message.AccountChannels;
13 |
14 | @Component("activeMQAccountChangedPublisher")
15 | public class ActiveMQAccountChangedPublisher extends AbstractAccountChangedPublisher {
16 |
17 | @Autowired
18 | private JmsTemplate jmsTemplate;
19 |
20 | @Override
21 | protected void publishEvent(AccountChangedEvent event) {
22 | jmsTemplate.convertAndSend(AccountChannels.SPRINGCSS_ACCOUNT_QUEUE, event, this::addEventSource);
23 | }
24 |
25 | private Message addEventSource(Message message) throws JMSException {
26 | message.setStringProperty("EVENT_SYSTEM", "SpringCSS");
27 | return message;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/jms/ActiveMQMessagingConfig.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message.jms;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
9 |
10 | import com.springcss.message.AccountChangedEvent;
11 |
12 | @Configuration
13 | public class ActiveMQMessagingConfig {
14 |
15 | @Bean
16 | public MappingJackson2MessageConverter activeMQMessageConverter() {
17 | MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
18 | messageConverter.setTypeIdPropertyName("_typeId");
19 |
20 | Map> typeIdMappings = new HashMap>();
21 | typeIdMappings.put("accountChangedEvent", AccountChangedEvent.class);
22 | messageConverter.setTypeIdMappings(typeIdMappings);
23 |
24 | return messageConverter;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/message/kafka/KafkaAccountChangedPublisher.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.message.kafka;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.kafka.core.KafkaTemplate;
5 | import org.springframework.stereotype.Component;
6 |
7 | import com.springcss.account.message.AbstractAccountChangedPublisher;
8 | import com.springcss.message.AccountChangedEvent;
9 | import com.springcss.message.AccountChannels;
10 |
11 | @Component("kafkaAccountChangedPublisher")
12 | public class KafkaAccountChangedPublisher extends AbstractAccountChangedPublisher {
13 |
14 | @Autowired
15 | private KafkaTemplate kafkaTemplate;
16 |
17 | @Override
18 | protected void publishEvent(AccountChangedEvent event) {
19 | kafkaTemplate.send(AccountChannels.SPRINGCSS_ACCOUNT_TOPIC, event);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/repository/AccountRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import com.springcss.account.domain.Account;
7 |
8 | @Repository
9 | public interface AccountRepository extends JpaRepository {
10 |
11 | Account findAccountByAccountName(String accountName);
12 | }
13 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/security/SpringCssSecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.security;
2 |
3 | import javax.sql.DataSource;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpMethod;
8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
11 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
12 |
13 | @Configuration
14 | public class SpringCssSecurityConfig extends WebSecurityConfigurerAdapter {
15 |
16 | // @Override
17 | // protected void configure(AuthenticationManagerBuilder builder) throws
18 | // Exception {
19 | //
20 | // builder.inMemoryAuthentication().withUser("springcss_user").password("password1").roles("USER").and()
21 | // .withUser("springcss_admin").password("password2").roles("USER", "ADMIN");
22 | // }
23 |
24 | @Autowired
25 | DataSource dataSource;
26 |
27 | @Override
28 | protected void configure(AuthenticationManagerBuilder auth) throws Exception {
29 |
30 | auth.jdbcAuthentication().dataSource(dataSource)
31 | .usersByUsernameQuery("select username, password, enabled from Users " + "where username=?")
32 | .authoritiesByUsernameQuery("select username, authority from UserAuthorities " + "where username=?")
33 | .passwordEncoder(new BCryptPasswordEncoder());
34 |
35 | }
36 |
37 | // @Autowired
38 | // SpringCssUserDetailsService springCssUserDetailsService;
39 | //
40 | // @Override
41 | // protected void configure(AuthenticationManagerBuilder auth) throws Exception {
42 | //
43 | // auth.userDetailsService(springCssUserDetailsService);
44 | // }
45 |
46 |
47 |
48 | @Override
49 | public void configure(HttpSecurity http) throws Exception {
50 |
51 | // http.authorizeRequests()
52 | // .antMatchers("/accounts/**")
53 | // .authenticated();
54 |
55 | // http.authorizeRequests()
56 | // .antMatchers("/accounts")
57 | // .access("hasRole('ROLE_USER')");
58 |
59 |
60 |
61 | http.authorizeRequests()
62 | .antMatchers(HttpMethod.DELETE, "accounts/**")
63 | .hasRole("ADMIN")
64 | .anyRequest()
65 | .authenticated();
66 |
67 | // http.authorizeRequests()
68 | // .antMatchers("/design", "/orders")
69 | // .access("hasRole('ROLE_USER')");
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/security/SpringCssUser.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.security;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collection;
5 |
6 | import org.springframework.security.core.GrantedAuthority;
7 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
8 | import org.springframework.security.core.userdetails.UserDetails;
9 |
10 | public class SpringCssUser implements UserDetails {
11 |
12 | private static final long serialVersionUID = 1L;
13 | private Long id;
14 | private final String username;
15 | private final String password;
16 | private final String phoneNumber;
17 |
18 | public Long getId() {
19 | return id;
20 | }
21 |
22 | public SpringCssUser(Long id, String username, String password, String phoneNumber) {
23 | super();
24 | this.id = id;
25 | this.username = username;
26 | this.password = password;
27 | this.phoneNumber = phoneNumber;
28 | }
29 |
30 | public void setId(Long id) {
31 | this.id = id;
32 | }
33 |
34 | @Override
35 | public String getUsername() {
36 | return username;
37 | }
38 |
39 | @Override
40 | public String getPassword() {
41 | return password;
42 | }
43 |
44 | public String getPhoneNumber() {
45 | return phoneNumber;
46 | }
47 |
48 | @Override
49 | public Collection extends GrantedAuthority> getAuthorities() {
50 | return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
51 | }
52 |
53 | @Override
54 | public boolean isAccountNonExpired() {
55 | return true;
56 | }
57 |
58 | @Override
59 | public boolean isAccountNonLocked() {
60 | return true;
61 | }
62 |
63 | @Override
64 | public boolean isCredentialsNonExpired() {
65 | return true;
66 | }
67 |
68 | @Override
69 | public boolean isEnabled() {
70 | return true;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/security/SpringCssUserDetailsService.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.security;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.security.core.userdetails.UserDetails;
5 | import org.springframework.security.core.userdetails.UserDetailsService;
6 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
7 | import org.springframework.stereotype.Service;
8 |
9 | @Service
10 | public class SpringCssUserDetailsService implements UserDetailsService {
11 |
12 | @Autowired
13 | private SpringCssUserRepository repository;
14 |
15 | @Override
16 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
17 | SpringCssUser user = repository.findByUsername(username);
18 | if (user != null) {
19 | return user;
20 | }
21 | throw new UsernameNotFoundException("SpringCSS User '" + username + "' not found");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/security/SpringCssUserRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.security;
2 |
3 | import org.springframework.data.repository.CrudRepository;
4 |
5 | public interface SpringCssUserRepository extends CrudRepository {
6 |
7 | SpringCssUser findByUsername(String username);
8 | }
9 |
--------------------------------------------------------------------------------
/account-service/src/main/java/com/springcss/account/service/AccountService.java:
--------------------------------------------------------------------------------
1 | package com.springcss.account.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.beans.factory.annotation.Qualifier;
5 | import org.springframework.stereotype.Service;
6 |
7 | import com.springcss.account.domain.Account;
8 | import com.springcss.account.message.AccountChangedPublisher;
9 | import com.springcss.account.repository.AccountRepository;
10 |
11 | @Service
12 | public class AccountService {
13 |
14 | @Autowired
15 | // @Qualifier("kafkaAccountChangedPublisher")
16 | // @Qualifier("activeMQAccountChangedPublisher")
17 | @Qualifier("rabbitMQAccountChangedPublisher")
18 | private AccountChangedPublisher publisher;
19 |
20 | @Autowired
21 | private AccountRepository accountRepository;
22 |
23 | public Account getAccountById(Long accountId) {
24 |
25 | return accountRepository.getOne(accountId);
26 | }
27 |
28 | public Account getAccountByAccountName(String accountName) {
29 |
30 | return accountRepository.findAccountByAccountName(accountName);
31 | }
32 |
33 | public void addAccount(Account account){
34 | // accountRepository.save(account);
35 |
36 | publisher.publishAccountChangedEvent(account, "ADD");
37 | }
38 |
39 | public void updateAccount(Account account){
40 | // accountRepository.save(account);
41 |
42 | publisher.publishAccountChangedEvent(account, "UPDATE");
43 | }
44 |
45 | public void deleteAccount(Account account){
46 | accountRepository.delete(account);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/account-service/src/main/resources/META-INF/additional-spring-configuration-metadata.json:
--------------------------------------------------------------------------------
1 | {"properties": [{
2 | "name": "springcss.order.point",
3 | "type": "java.lang.String",
4 | "description": "'springcss.order.point' is userd for setting the point when dealing with an order.",
5 | "defaultValue": 10
6 | }]}
--------------------------------------------------------------------------------
/account-service/src/main/resources/account.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `account`;
2 |
3 | CREATE TABLE `account` (
4 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
5 | `account_code` varchar(20) DEFAULT NULL,
6 | `account_name` varchar(100) DEFAULT NULL,
7 | PRIMARY KEY (`id`)
8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
9 |
10 | INSERT INTO `user` VALUES ('1', 'account1', 'springcss_account1');
11 | INSERT INTO `user` VALUES ('2', 'account2', 'springcss_account2');
--------------------------------------------------------------------------------
/account-service/src/main/resources/application-activemq.yml:
--------------------------------------------------------------------------------
1 |
2 | spring:
3 | jms:
4 | template:
5 | default-destination: springcss.account.queue
6 | artemis:
7 | host: localhost
8 | port: 61616
9 | user: springcss
10 | password: springcss_password
11 | embedded:
12 | enabled: false
--------------------------------------------------------------------------------
/account-service/src/main/resources/application-kafka.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | kafka:
3 | bootstrap-servers:
4 | - localhost:9092
5 | template:
6 | default-topic: springcss.account.topic
7 | producer:
8 | keySerializer: org.springframework.kafka.support.serializer.JsonSerializer
9 | valueSerializer: org.springframework.kafka.support.serializer.JsonSerializer
--------------------------------------------------------------------------------
/account-service/src/main/resources/application-rabbitmq.yml:
--------------------------------------------------------------------------------
1 |
2 | spring:
3 | rabbitmq:
4 | host: 127.0.0.1
5 | port: 5672
6 | username: guest
7 | password: guest
8 | virtual-host: SpringCSSHost
--------------------------------------------------------------------------------
/account-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8082
3 |
4 | management:
5 | endpoints:
6 | web:
7 | exposure:
8 | include: "*"
9 | endpoint:
10 | health:
11 | show-details: always
12 |
13 | logging:
14 | level:
15 | com.netflix: WARN
16 | org.springframework.web: WARN
17 | com.tianyalan: INFO
18 |
19 |
20 | spring:
21 | profiles:
22 | active: activemq
23 | # security:
24 | # user:
25 | # name: springcss
26 | # password: springcss_password
27 |
28 |
--------------------------------------------------------------------------------
/account-service/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: accountservice
4 | profiles:
5 | active:
6 | default
7 | boot:
8 | admin:
9 | client:
10 | url: http://localhost:9000
11 |
12 |
13 | springcss:
14 | order:
15 | point: 10
16 |
17 |
--------------------------------------------------------------------------------
/admin-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.springcss
8 | admin-server
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | Admin Server
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-hateoas
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-actuator
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-data-rest
33 |
34 |
35 |
36 | de.codecentric
37 | spring-boot-admin-server
38 | 2.2.3
39 |
40 |
41 | de.codecentric
42 | spring-boot-admin-server-ui
43 | 2.2.3
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-web
49 |
50 |
51 |
52 | org.springframework.boot
53 | spring-boot-starter-security
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | org.springframework.boot
62 | spring-boot-maven-plugin
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/admin-server/src/main/java/com/springcss/admin/AdminApplication.java:
--------------------------------------------------------------------------------
1 | package com.springcss.admin;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | import de.codecentric.boot.admin.server.config.EnableAdminServer;
7 |
8 | @SpringBootApplication
9 | @EnableAdminServer
10 | public class AdminApplication {
11 |
12 | public static void main(String[] args) {
13 | SpringApplication.run(AdminApplication.class, args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/admin-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 9000
3 |
4 | management:
5 | endpoints:
6 | web:
7 | exposure:
8 | include: "*"
9 |
10 | logging:
11 | level:
12 | com.netflix: WARN
13 | org.springframework.web: WARN
14 | com.tianyalan: INFO
15 |
16 |
17 | eureka:
18 | client:
19 | register-with-eureka: false
20 |
21 | spring:
22 | security:
23 | user:
24 | name: "springcss_admin"
25 | password: "springcss_password"
26 |
--------------------------------------------------------------------------------
/customer-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.springcss
8 | customer-service
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | Customer Service
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 |
23 | com.springcss
24 | message
25 | 0.0.1-SNAPSHOT
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-data-jpa
31 |
32 |
33 | org.springframework.boot
34 | spring-boot-starter-web
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-hateoas
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-actuator
44 |
45 |
46 | org.springframework.boot
47 | spring-boot-starter-data-rest
48 |
49 |
50 |
51 | com.h2database
52 | h2
53 |
54 |
55 |
56 | mysql
57 | mysql-connector-java
58 |
59 |
60 |
61 | org.apache.commons
62 | commons-pool2
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-starter-amqp
68 |
69 |
70 |
82 |
83 |
84 | org.springframework.boot
85 | spring-boot-starter-test
86 | test
87 |
88 |
89 |
90 | org.junit.platform
91 | junit-platform-launcher
92 | test
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | org.springframework.boot
101 | spring-boot-maven-plugin
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/CustomerApplication.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import java.net.UnknownHostException;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
9 | import org.springframework.boot.autoconfigure.SpringBootApplication;
10 | //import org.springframework.cloud.stream.annotation.EnableBinding;
11 | //import org.springframework.cloud.stream.messaging.Sink;
12 | import org.springframework.context.annotation.Bean;
13 | import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
14 | import org.springframework.http.converter.HttpMessageConverter;
15 | import org.springframework.http.converter.json.GsonHttpMessageConverter;
16 | import org.springframework.web.client.RestTemplate;
17 |
18 | import io.micrometer.core.instrument.MeterRegistry;
19 |
20 | @SpringBootApplication
21 | public class CustomerApplication {
22 |
23 |
24 | @Bean
25 | public RestTemplate restTemplate() {
26 | return new RestTemplate();
27 | }
28 |
29 | // @Bean
30 | // public RestTemplate restTemplate() {
31 | // // return new RestTemplate();
32 | //
33 | //// RestTemplate restTemplate = new RestTemplate();
34 | // // 获取RestTemplate默认配置好的所有转换器
35 | //// List> messageConverters = restTemplate.getMessageConverters();
36 | //// // 默认的MappingJackson2HttpMessageConverter在第7个 先把它移除掉
37 | //// messageConverters.remove(6);
38 | //// // 添加上GSON的转换器
39 | //// messageConverters.add(6, new GsonHttpMessageConverter());
40 | //
41 | //
42 | // List> messageConverters = new ArrayList>();
43 | // messageConverters.add(new GsonHttpMessageConverter());
44 | // RestTemplate restTemplate = new RestTemplate(messageConverters);
45 | // return restTemplate;
46 | // }
47 | //
48 | //
49 | // @Bean
50 | // public RestTemplate customRestTemplate() {
51 | // HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
52 | // httpRequestFactory.setConnectionRequestTimeout(3000);
53 | // httpRequestFactory.setConnectTimeout(3000);
54 | // httpRequestFactory.setReadTimeout(3000);
55 | //
56 | // return new RestTemplate(httpRequestFactory);
57 | // }
58 |
59 |
60 | // @Bean
61 | // public MeterRegistryCustomizer meterRegistryCustomizer() {
62 | // return registry -> registry.config().commonTags("tag1", "a", "tag2", "b");
63 | // }
64 |
65 | public static void main(String[] args) {
66 | SpringApplication.run(CustomerApplication.class, args);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/client/OrderClient.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.client;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.http.HttpMethod;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.stereotype.Component;
9 | import org.springframework.web.client.RestTemplate;
10 |
11 | @Component
12 | public class OrderClient {
13 |
14 | private static final Logger logger = LoggerFactory.getLogger(OrderClient.class);
15 |
16 | @Autowired
17 | RestTemplate restTemplate;
18 |
19 | public OrderMapper getOrderByOrderNumber(String orderNumber) {
20 |
21 | logger.debug("Get order: {}", orderNumber);
22 |
23 | ResponseEntity restExchange = restTemplate.exchange(
24 | "http://localhost:8083/orders/{orderNumber}", HttpMethod.GET, null,
25 | OrderMapper.class, orderNumber);
26 |
27 | OrderMapper result = restExchange.getBody();
28 |
29 | return result;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/client/OrderMapper.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.client;
2 |
3 | import java.io.Serializable;
4 |
5 | public class OrderMapper implements Serializable {
6 | private static final long serialVersionUID = 1L;
7 |
8 | private Long id;
9 | private String orderNumber;
10 | private String deliveryAddress;
11 |
12 | public OrderMapper(Long id, String orderNumber, String deliveryAddress) {
13 | super();
14 | this.id = id;
15 | this.orderNumber = orderNumber;
16 | this.deliveryAddress = deliveryAddress;
17 | }
18 | public Long getId() {
19 | return id;
20 | }
21 | public void setId(Long id) {
22 | this.id = id;
23 | }
24 | public String getOrderNumber() {
25 | return orderNumber;
26 | }
27 | public void setOrderNumber(String orderNumber) {
28 | this.orderNumber = orderNumber;
29 | }
30 | public String getDeliveryAddress() {
31 | return deliveryAddress;
32 | }
33 | public void setDeliveryAddress(String deliveryAddress) {
34 | this.deliveryAddress = deliveryAddress;
35 | }
36 | }
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/controller/CustomerController.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.controller;
2 |
3 | import java.util.Date;
4 | import java.util.List;
5 |
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.DeleteMapping;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.PathVariable;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.RequestMethod;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import com.springcss.customer.domain.CustomerTicket;
16 | import com.springcss.customer.service.CustomerTicketService;
17 |
18 | @RestController
19 | @RequestMapping(value="customers")
20 | public class CustomerController {
21 |
22 | @Autowired
23 | private CustomerTicketService customerTicketService;
24 |
25 | @PostMapping(value = "/{accountId}/{orderNumber}")
26 | public CustomerTicket generateCustomerTicket( @PathVariable("accountId") Long accountId,
27 | @PathVariable("orderNumber") String orderNumber) {
28 |
29 | CustomerTicket customerTicket = customerTicketService.generateCustomerTicket(accountId, orderNumber);
30 |
31 | return customerTicket;
32 | }
33 |
34 | @GetMapping(value = "/{id}")
35 | public CustomerTicket getCustomerTicketById(@PathVariable Long id) {
36 |
37 | // CustomerTicket customerTicket = customerTicketService.getCustomerTicketById(id);
38 |
39 | CustomerTicket customerTicket = new CustomerTicket();
40 | customerTicket.setId(1L);
41 | customerTicket.setAccountId(100L);
42 | customerTicket.setOrderNumber("Order00001");
43 | customerTicket.setDescription("DemoOrder");
44 | customerTicket.setCreateTime(new Date());
45 |
46 | return customerTicket;
47 | }
48 |
49 | @GetMapping(value = "/{pageIndex}/{pageSize}")
50 | public List getCustomerTicketList( @PathVariable("pageIndex") int pageIndex, @PathVariable("pageSize") int pageSize) {
51 | List customerTickets = customerTicketService.getCustomerTickets(pageIndex, pageSize);
52 |
53 | return customerTickets;
54 | }
55 |
56 | @DeleteMapping(value = "/{id}")
57 | public void deleteCustomerTicket( @PathVariable("id") Long id) {
58 |
59 | customerTicketService.deleteCustomerTicket(id);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/controller/HealthController.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.controller;
2 |
3 | import org.springframework.web.bind.annotation.RequestMapping;
4 | import org.springframework.web.bind.annotation.RequestMethod;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | @RestController
8 | @RequestMapping(value="health")
9 | public class HealthController {
10 |
11 | @RequestMapping(value = "/", method = RequestMethod.GET)
12 | public String checkHealth() {
13 | return "I am OK!";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/controller/MessageReceiveController.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.controller;
2 | //
3 | //import org.springframework.beans.factory.annotation.Autowired;
4 | //import org.springframework.beans.factory.annotation.Qualifier;
5 | //import org.springframework.web.bind.annotation.RequestMapping;
6 | //import org.springframework.web.bind.annotation.RequestMethod;
7 | //import org.springframework.web.bind.annotation.RestController;
8 | //
9 | //import com.springcss.customer.message.AccountChangedReceiver;
10 | //
11 | //@RestController
12 | //@RequestMapping(value="messagereceive")
13 | //public class MessageReceiveController {
14 | //
15 | // @Autowired
16 | //// @Qualifier("activeMQAccountChangedReceiver")
17 | // @Qualifier("rabbitMQAccountChangedReceiver")
18 | // private AccountChangedReceiver accountChangedReceiver;
19 | //
20 | // @RequestMapping(value = "", method = RequestMethod.GET)
21 | // public void receiveAccountChangedEvent() {
22 | // accountChangedReceiver.receiveAccountChangedEvent();
23 | // }
24 | //}
25 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/domain/CustomerTicket.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.domain;
2 |
3 | import java.util.Date;
4 |
5 | import javax.persistence.Entity;
6 | import javax.persistence.GeneratedValue;
7 | import javax.persistence.Id;
8 | import javax.persistence.Table;
9 |
10 | import org.springframework.util.Assert;
11 |
12 | @Entity
13 | @Table(name = "customer_ticket")
14 | public class CustomerTicket {
15 | @Id
16 | @GeneratedValue
17 | private Long id;
18 | private Long accountId;
19 | private String orderNumber;
20 | private String description;
21 | private Date createTime;
22 |
23 |
24 | public CustomerTicket() {
25 | super();
26 | }
27 |
28 | public CustomerTicket(Long accountId, String orderNumber) {
29 | super();
30 |
31 | Assert.notNull(accountId, "Account Id must not be null");
32 | Assert.notNull(orderNumber, "Order Number must not be null");
33 | Assert.isTrue(orderNumber.length() == 10, "Order Number must be exactly 10 characters");
34 |
35 | this.accountId = accountId;
36 | this.orderNumber = orderNumber;
37 | }
38 |
39 | public CustomerTicket(Long accountId, String orderNumber, String description, Date createTime) {
40 |
41 | this(accountId, orderNumber);
42 |
43 | this.description = description;
44 | this.createTime = createTime;
45 | }
46 |
47 | public CustomerTicket(Long id, Long accountId, String orderNumber, String description, Date createTime) {
48 |
49 | this(accountId, orderNumber);
50 |
51 | this.id = id;
52 | this.description = description;
53 | this.createTime = createTime;
54 | }
55 |
56 | public Long getId() {
57 | return id;
58 | }
59 | public void setId(Long id) {
60 | this.id = id;
61 | }
62 | public Long getAccountId() {
63 | return accountId;
64 | }
65 | public void setAccountId(Long accountId) {
66 | this.accountId = accountId;
67 | }
68 | public String getOrderNumber() {
69 | return orderNumber;
70 | }
71 | public void setOrderNumber(String orderNumber) {
72 | this.orderNumber = orderNumber;
73 | }
74 | public String getDescription() {
75 | return description;
76 | }
77 | public void setDescription(String description) {
78 | this.description = description;
79 | }
80 | public Date getCreateTime() {
81 | return createTime;
82 | }
83 | public void setCreateTime(Date createTime) {
84 | this.createTime = createTime;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/domain/LocalAccount.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.domain;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.Id;
6 | import javax.persistence.Table;
7 |
8 | @Entity
9 | @Table(name = "localaccount")
10 | public class LocalAccount {
11 | @Id
12 | @GeneratedValue
13 | private Long id;
14 | private String accountCode;
15 | private String accountName;
16 |
17 | public LocalAccount(Long id, String accountCode, String accountName) {
18 | super();
19 | this.id = id;
20 | this.accountCode = accountCode;
21 | this.accountName = accountName;
22 | }
23 |
24 | public Long getId() {
25 | return id;
26 | }
27 | public void setId(Long id) {
28 | this.id = id;
29 | }
30 | public String getAccountCode() {
31 | return accountCode;
32 | }
33 | public void setAccountCode(String accountCode) {
34 | this.accountCode = accountCode;
35 | }
36 | public String getAccountName() {
37 | return accountName;
38 | }
39 | public void setAccountName(String accountName) {
40 | this.accountName = accountName;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/AbstractAccountChangedReceiver.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.message;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 |
5 | import com.springcss.customer.domain.LocalAccount;
6 | import com.springcss.customer.repository.LocalAccountRepository;
7 | import com.springcss.message.AccountChangedEvent;
8 | import com.springcss.message.AccountMessage;
9 |
10 | public abstract class AbstractAccountChangedReceiver implements AccountChangedReceiver {
11 |
12 | @Autowired
13 | LocalAccountRepository localAccountRepository;
14 |
15 | @Override
16 | public void receiveAccountChangedEvent() {
17 |
18 | AccountChangedEvent event = receiveEvent();
19 |
20 | handleEvent(event);
21 | }
22 |
23 | protected void handleEvent(AccountChangedEvent event) {
24 | AccountMessage account = event.getAccountMessage();
25 | String operation = event.getOperation();
26 |
27 | operateAccount(account, operation);
28 | }
29 |
30 | private void operateAccount(AccountMessage accountMessage, String operation) {
31 | System.out.print(
32 | accountMessage.getId() + ":" + accountMessage.getAccountCode() + ":" + accountMessage.getAccountName());
33 |
34 | LocalAccount localAccount = new LocalAccount(accountMessage.getId(), accountMessage.getAccountCode(),
35 | accountMessage.getAccountName());
36 |
37 | if (operation.equals("ADD") || operation.equals("UPDATE")) {
38 | localAccountRepository.save(localAccount);
39 | } else {
40 | localAccountRepository.delete(localAccount);
41 | }
42 | }
43 |
44 | protected abstract AccountChangedEvent receiveEvent();
45 | }
46 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/AccountChangedReceiver.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.message;
2 |
3 | import com.springcss.message.AccountChangedEvent;
4 |
5 | public interface AccountChangedReceiver {
6 |
7 | //Pull模式下的消息接收方法
8 | void receiveAccountChangedEvent();
9 |
10 | //Push模式下的消息接收方法
11 | void handlerAccountChangedEvent(AccountChangedEvent event);
12 | }
13 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/amqp/RabbitMQAccountChangedReceiver.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.message.amqp;
2 | //
3 | //import org.springframework.amqp.rabbit.annotation.RabbitListener;
4 | //import org.springframework.amqp.rabbit.core.RabbitTemplate;
5 | //import org.springframework.beans.factory.annotation.Autowired;
6 | //import org.springframework.stereotype.Component;
7 | //
8 | //import com.springcss.customer.message.AbstractAccountChangedReceiver;
9 | //import com.springcss.message.AccountChangedEvent;
10 | //import com.springcss.message.AccountChannels;
11 | //
12 | //@Component("rabbitMQAccountChangedReceiver")
13 | //public class RabbitMQAccountChangedReceiver extends AbstractAccountChangedReceiver {
14 | //
15 | // @Autowired
16 | // private RabbitTemplate rabbitTemplate;
17 | //
18 | // @Override
19 | // public AccountChangedEvent receiveEvent() {
20 | // return (AccountChangedEvent) rabbitTemplate.receiveAndConvert(AccountChannels.SPRINGCSS_ACCOUNT_QUEUE);
21 | // }
22 | //
23 | // @Override
24 | // @RabbitListener(queues = AccountChannels.SPRINGCSS_ACCOUNT_QUEUE)
25 | // public void handlerAccountChangedEvent(AccountChangedEvent event) {
26 | // super.handleEvent(event);
27 | // }
28 | //}
29 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/amqp/RabbitMQMessagingConfig.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.message.amqp;
2 | //
3 | //import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
4 | //import org.springframework.context.annotation.Bean;
5 | //import org.springframework.context.annotation.Configuration;
6 | //
7 | //@Configuration
8 | //public class RabbitMQMessagingConfig {
9 | //
10 | // @Bean
11 | // public Jackson2JsonMessageConverter rabbitMQMessageConverter() {
12 | // return new Jackson2JsonMessageConverter();
13 | // }
14 | //}
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/jms/ActiveMQAccountChangedReceiver.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.message.jms;
2 | //
3 | //import org.springframework.beans.factory.annotation.Autowired;
4 | //import org.springframework.jms.annotation.JmsListener;
5 | //import org.springframework.jms.core.JmsTemplate;
6 | //import org.springframework.stereotype.Component;
7 | //
8 | //import com.springcss.customer.message.AbstractAccountChangedReceiver;
9 | //import com.springcss.message.AccountChangedEvent;
10 | //import com.springcss.message.AccountChannels;
11 | //
12 | //@Component("activeMQAccountChangedReceiver")
13 | //public class ActiveMQAccountChangedReceiver extends AbstractAccountChangedReceiver {
14 | //
15 | // @Autowired
16 | // private JmsTemplate jmsTemplate;
17 | //
18 | // @Override
19 | // protected AccountChangedEvent receiveEvent() {
20 | // return (AccountChangedEvent) jmsTemplate.receiveAndConvert(AccountChannels.SPRINGCSS_ACCOUNT_QUEUE);
21 | // }
22 | //
23 | // @Override
24 | // @JmsListener(destination = AccountChannels.SPRINGCSS_ACCOUNT_QUEUE)
25 | // public void handlerAccountChangedEvent(AccountChangedEvent event) {
26 | //
27 | // super.handleEvent(event);
28 | // }
29 | //}
30 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/jms/ActiveMQMessagingConfig.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.message.jms;
2 | //
3 | //import java.util.HashMap;
4 | //import java.util.Map;
5 | //
6 | //import org.springframework.context.annotation.Bean;
7 | //import org.springframework.context.annotation.Configuration;
8 | //import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
9 | //
10 | //import com.springcss.message.AccountChangedEvent;
11 | //
12 | //@Configuration
13 | //public class ActiveMQMessagingConfig {
14 | //
15 | // @Bean
16 | // public MappingJackson2MessageConverter activeMQMessageConverter() {
17 | // MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
18 | // messageConverter.setTypeIdPropertyName("_typeId");
19 | //
20 | // Map> typeIdMappings = new HashMap>();
21 | // typeIdMappings.put("accountChangedEvent", AccountChangedEvent.class);
22 | // messageConverter.setTypeIdMappings(typeIdMappings);
23 | //
24 | // return messageConverter;
25 | // }
26 | //
27 | //}
28 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/message/kafka/KafkaAccountChangedListener.java:
--------------------------------------------------------------------------------
1 | //package com.springcss.customer.message.kafka;
2 | //
3 | //import org.springframework.kafka.annotation.KafkaListener;
4 | //import org.springframework.stereotype.Component;
5 | //
6 | //import com.springcss.customer.message.AbstractAccountChangedReceiver;
7 | //import com.springcss.message.AccountChangedEvent;
8 | //import com.springcss.message.AccountChannels;
9 | //
10 | //@Component
11 | //public class KafkaAccountChangedListener extends AbstractAccountChangedReceiver {
12 | //
13 | // @Override
14 | // @KafkaListener(topics = AccountChannels.SPRINGCSS_ACCOUNT_TOPIC)
15 | // public void handlerAccountChangedEvent(AccountChangedEvent event) {
16 | //
17 | // super.handleEvent(event);
18 | // }
19 | //
20 | // @Override
21 | // protected AccountChangedEvent receiveEvent() {
22 | // return null;
23 | // }
24 | //}
25 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/metrics/CounterService.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.metrics;
2 |
3 | import org.springframework.stereotype.Component;
4 |
5 | import io.micrometer.core.instrument.Counter;
6 | import io.micrometer.core.instrument.Metrics;
7 | import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
8 |
9 | @Component
10 | public class CounterService {
11 |
12 | public CounterService() {
13 | Metrics.addRegistry(new SimpleMeterRegistry());
14 | }
15 |
16 | public void counter(String name, String... tags) {
17 | Counter counter = Metrics.counter(name, tags);
18 | counter.increment();
19 | }
20 | }
21 |
22 |
23 |
24 |
25 | //@Autowired
26 | //private MeterRegistry registry;
27 | //
28 | //public void counter(String name, String... tags) {
29 | // Counter counter = registry.counter(name, tags);
30 | // counter.increment();
31 | //}
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/metrics/CustomerTicketMetrics.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.metrics;
2 |
3 | import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
4 | import org.springframework.stereotype.Component;
5 |
6 | import com.springcss.customer.domain.CustomerTicket;
7 |
8 | import io.micrometer.core.instrument.MeterRegistry;
9 |
10 | @Component
11 | public class CustomerTicketMetrics extends AbstractRepositoryEventListener {
12 |
13 | private MeterRegistry meterRegistry;
14 |
15 | public CustomerTicketMetrics(MeterRegistry meterRegistry) {
16 | this.meterRegistry = meterRegistry;
17 | }
18 |
19 | @Override
20 | protected void onAfterCreate(CustomerTicket customerTicket) {
21 | // meterRegistry.counter("customerTicket.created.count").increment();
22 |
23 | meterRegistry.summary("customerTicket.created.count").record(1);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/repository/CustomerTicketRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.repository;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.jpa.repository.JpaRepository;
6 | import org.springframework.stereotype.Repository;
7 |
8 | import com.springcss.customer.domain.CustomerTicket;
9 |
10 | @Repository
11 | public interface CustomerTicketRepository extends JpaRepository {
12 |
13 | List getCustomerTicketByOrderNumber(String orderNumber);
14 | }
15 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/repository/LocalAccountRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.stereotype.Repository;
5 |
6 | import com.springcss.customer.domain.LocalAccount;
7 |
8 | @Repository
9 | public interface LocalAccountRepository extends JpaRepository{
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/customer-service/src/main/java/com/springcss/customer/service/CustomerTicketService.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer.service;
2 |
3 | import java.util.Date;
4 | import java.util.List;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.data.domain.PageRequest;
10 | import org.springframework.data.domain.Sort;
11 | import org.springframework.stereotype.Service;
12 |
13 | import com.springcss.customer.client.OrderClient;
14 | import com.springcss.customer.client.OrderMapper;
15 | import com.springcss.customer.domain.LocalAccount;
16 | import com.springcss.customer.metrics.CounterService;
17 | import com.springcss.customer.domain.CustomerTicket;
18 | import com.springcss.customer.repository.CustomerTicketRepository;
19 | import com.springcss.customer.repository.LocalAccountRepository;
20 |
21 | import io.micrometer.core.instrument.MeterRegistry;
22 |
23 | @Service
24 | public class CustomerTicketService {
25 |
26 | @Autowired
27 | private CustomerTicketRepository customerTicketRepository;
28 |
29 | @Autowired
30 | private LocalAccountRepository localAccountRepository;
31 |
32 | @Autowired
33 | private OrderClient orderClient;
34 |
35 | // @Autowired
36 | // private CounterService customerTicketCounterService;
37 |
38 | @Autowired
39 | private MeterRegistry meterRegistry;
40 |
41 | private static final Logger logger = LoggerFactory.getLogger(CustomerTicketService.class);
42 |
43 | private OrderMapper getRemoteOrderByOrderNumber(String orderNumber) {
44 |
45 | return orderClient.getOrderByOrderNumber(orderNumber);
46 | }
47 |
48 | public CustomerTicket generateCustomerTicket(Long accountId, String orderNumber) {
49 |
50 | logger.debug("Generate customer ticket record with account: {} and order: {}", accountId, orderNumber);
51 |
52 | CustomerTicket customerTicket = new CustomerTicket();
53 |
54 | // 从本地数据库中获取Account信息
55 | LocalAccount account = getAccountById(accountId);
56 | if (account != null) {
57 | return customerTicket;
58 | }
59 |
60 | // 从远程order-service中获取Order信息
61 | OrderMapper order = getRemoteOrderByOrderNumber(orderNumber);
62 | if (order == null) {
63 | return customerTicket;
64 | }
65 | logger.debug("Get remote order: {} is successful", orderNumber);
66 |
67 | // 创建并保存CustomerTicket信息
68 | customerTicket.setAccountId(accountId);
69 | customerTicket.setOrderNumber(order.getOrderNumber());
70 | customerTicket.setCreateTime(new Date());
71 | customerTicket.setDescription("TestCustomerTicket");
72 | customerTicketRepository.save(customerTicket);
73 |
74 | // 添加Metrics
75 | // customerTicketCounterService.counter("customerTicket.created.count");
76 | meterRegistry.summary("customerTickets.generated.count").record(1);
77 |
78 | return customerTicket;
79 | }
80 |
81 | public List getCustomerTickets(int pageIndex, int pageSize) {
82 |
83 | return customerTicketRepository.findAll(PageRequest.of(pageIndex - 1, pageSize, Sort.DEFAULT_DIRECTION))
84 | .getContent();
85 | }
86 |
87 | public CustomerTicket getCustomerTicketById(Long id) {
88 | return customerTicketRepository.getOne(id);
89 | }
90 |
91 | public void deleteCustomerTicket(Long id) {
92 | customerTicketRepository.deleteById(id);
93 | }
94 |
95 | private LocalAccount getAccountById(Long accountId) {
96 | return localAccountRepository.getOne(accountId);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/customer-service/src/main/resources/application-activemq.yml:
--------------------------------------------------------------------------------
1 |
2 | spring:
3 | jms:
4 | template:
5 | receive-timeout: 2
6 | artemis:
7 | host: localhost
8 | port: 61616
9 | user: springcss
10 | password: springcss_password
11 | embedded:
12 | enabled: false
--------------------------------------------------------------------------------
/customer-service/src/main/resources/application-kafka.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | kafka:
3 | bootstrap-servers:
4 | - localhost:9092
5 | template:
6 | default-topic: springcss.account.topic
7 | consumer:
8 | value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
9 | group-id: springcss_customer
10 | properties:
11 | spring.json.trusted.packages: com.springcss.message
12 |
--------------------------------------------------------------------------------
/customer-service/src/main/resources/application-rabbitmq.yml:
--------------------------------------------------------------------------------
1 |
2 | spring:
3 | rabbitmq:
4 | host: 127.0.0.1
5 | port: 5672
6 | username: guest
7 | password: guest
8 | virtual-host: SpringCSSHost
9 | template:
10 | receive-timeout: 30000
--------------------------------------------------------------------------------
/customer-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8083
3 |
4 | logging:
5 | level:
6 | com.netflix: WARN
7 | org.springframework.web: WARN
8 | com.tianyalan: INFO
9 |
10 | #spring:
11 | # profiles:
12 | # active: activemq
--------------------------------------------------------------------------------
/customer-service/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: customerservice
4 | profiles:
5 | active:
6 | default
--------------------------------------------------------------------------------
/customer-service/src/main/resources/customer.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `intervention`;
2 |
3 | CREATE TABLE `intervention`
4 | (
5 | id BIGINT(20) PRIMARY KEY NOT NULL,
6 | account_id BIGINT(20) NOT NULL,
7 | order_number varchar(50) NOT NULL,
8 | description varchar(255) DEFAULT NULL,
9 | create_time TIMESTAMP NOT NULL,
10 | )ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
11 |
12 |
13 |
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/ApplicationContextTests.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.context.ApplicationContext;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | @SpringBootTest
12 | @RunWith(SpringRunner.class)
13 | public class ApplicationContextTests {
14 |
15 | @Autowired
16 | private ApplicationContext applicationContext;
17 |
18 | @Test
19 | public void testContextLoads() throws Throwable {
20 | Assert.assertNotNull(this.applicationContext);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerControllerTestsWithAutoConfigureMockMvc.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import static org.mockito.BDDMockito.given;
4 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
5 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
6 |
7 | import java.util.Date;
8 |
9 | import org.junit.Test;
10 | import org.junit.runner.RunWith;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
13 | import org.springframework.boot.test.context.SpringBootTest;
14 | import org.springframework.boot.test.mock.mockito.MockBean;
15 | import org.springframework.http.MediaType;
16 | import org.springframework.test.context.junit4.SpringRunner;
17 | import org.springframework.test.web.servlet.MockMvc;
18 |
19 | import com.springcss.customer.domain.CustomerTicket;
20 | import com.springcss.customer.service.CustomerTicketService;
21 |
22 | @RunWith(SpringRunner.class)
23 | @SpringBootTest
24 | @AutoConfigureMockMvc
25 | public class CustomerControllerTestsWithAutoConfigureMockMvc {
26 |
27 | @Autowired
28 | private MockMvc mvc;
29 |
30 | @MockBean
31 | private CustomerTicketService customerTicketService;
32 |
33 | @Test
34 | public void testGenerateCustomerTicket() throws Exception {
35 | Long accountId = 100L;
36 | String orderNumber = "Order00001";
37 |
38 | given(this.customerTicketService.generateCustomerTicket(accountId, orderNumber))
39 | .willReturn(new CustomerTicket(1L, 100L, "Order00001", "DemoCustomerTicket1", new Date()));
40 |
41 | this.mvc.perform(post("/customers/" + accountId+ "/" + orderNumber).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
42 | }
43 | }
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerControllerTestsWithMockMvc.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
5 | import org.springframework.boot.test.mock.mockito.MockBean;
6 | import org.springframework.http.MediaType;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 | import org.springframework.test.web.servlet.MockMvc;
9 |
10 | import com.springcss.customer.controller.CustomerController;
11 | import com.springcss.customer.domain.CustomerTicket;
12 | import com.springcss.customer.service.CustomerTicketService;
13 |
14 | import java.util.Date;
15 |
16 | import org.junit.Test;
17 | import org.junit.runner.RunWith;
18 | import static org.mockito.BDDMockito.given;
19 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
20 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
21 |
22 | @RunWith(SpringRunner.class)
23 | @WebMvcTest(CustomerController.class)
24 | public class CustomerControllerTestsWithMockMvc {
25 |
26 | @Autowired
27 | private MockMvc mvc;
28 |
29 | @MockBean
30 | private CustomerTicketService customerTicketService;
31 |
32 | @Test
33 | public void testGenerateCustomerTicket() throws Exception {
34 | Long accountId = 100L;
35 | String orderNumber = "Order00001";
36 |
37 | given(this.customerTicketService.generateCustomerTicket(accountId, orderNumber))
38 | .willReturn(new CustomerTicket(1L, 100L, "Order00001", "DemoCustomerTicket1", new Date()));
39 |
40 | this.mvc.perform(post("/customers/" + accountId+ "/" + orderNumber).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
41 | }
42 | }
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerControllerTestsWithTestRestTemplate.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import static org.assertj.core.api.Assertions.assertThat;
4 | import static org.mockito.BDDMockito.given;
5 |
6 | import java.util.Date;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.boot.test.context.SpringBootTest;
12 | import org.springframework.boot.test.mock.mockito.MockBean;
13 | import org.springframework.boot.test.web.client.TestRestTemplate;
14 | import org.springframework.test.context.junit4.SpringRunner;
15 |
16 | import com.springcss.customer.domain.CustomerTicket;
17 | import com.springcss.customer.service.CustomerTicketService;
18 |
19 | @RunWith(SpringRunner.class)
20 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
21 | public class CustomerControllerTestsWithTestRestTemplate {
22 |
23 | @Autowired
24 | private TestRestTemplate testRestTemplate;
25 |
26 | @MockBean
27 | private CustomerTicketService customerTicketService;
28 |
29 | @Test
30 | public void testGenerateCustomerTicket() throws Exception {
31 | Long accountId = 100L;
32 | String orderNumber = "Order00001";
33 |
34 | given(this.customerTicketService.generateCustomerTicket(accountId, orderNumber))
35 | .willReturn(new CustomerTicket(1L, accountId, orderNumber , "DemoCustomerTicket1", new Date()));
36 |
37 | CustomerTicket actual = testRestTemplate.postForObject("/customers/" + accountId+ "/" + orderNumber, null, CustomerTicket.class);
38 | assertThat(actual.getOrderNumber()).isEqualTo(orderNumber);
39 | }
40 | }
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerRepositoryTest.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
7 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import com.springcss.customer.domain.CustomerTicket;
11 | import com.springcss.customer.repository.CustomerTicketRepository;
12 |
13 | import java.util.Date;
14 | import java.util.List;
15 |
16 | import static org.assertj.core.api.Assertions.assertThat;
17 |
18 | @RunWith(SpringRunner.class)
19 | @DataJpaTest
20 | public class CustomerRepositoryTest {
21 |
22 | @Autowired
23 | private TestEntityManager entityManager;
24 |
25 | @Autowired
26 | private CustomerTicketRepository customerTicketRepository;
27 |
28 | @Test
29 | public void testFindCustomerTicketById() throws Exception {
30 | this.entityManager.persist(new CustomerTicket(1L, "Order00001", "DemoCustomerTicket1", new Date()));
31 |
32 | CustomerTicket customerTicket = this.customerTicketRepository.getOne(1L);
33 | assertThat(customerTicket).isNotNull();
34 | assertThat(customerTicket.getId()).isEqualTo(1L);
35 | }
36 |
37 | @Test
38 | public void testFindCustomerTicketByOrderNumber() throws Exception {
39 | String orderNumber = "Order00001";
40 |
41 | this.entityManager.persist(new CustomerTicket(1L, orderNumber, "DemoCustomerTicket1", new Date()));
42 | this.entityManager.persist(new CustomerTicket(2L, orderNumber, "DemoCustomerTicket2", new Date()));
43 |
44 | List customerTickets = this.customerTicketRepository.getCustomerTicketByOrderNumber(orderNumber);
45 | assertThat(customerTickets).size().isEqualTo(2);
46 | CustomerTicket actual = customerTickets.get(0);
47 | assertThat(actual.getOrderNumber()).isEqualTo(orderNumber);
48 | }
49 |
50 | @Test
51 | public void testFindCustomerTicketByNonExistedOrderNumber() throws Exception {
52 | this.entityManager.persist(new CustomerTicket(1L, "Order00001", "DemoCustomerTicket1", new Date()));
53 | this.entityManager.persist(new CustomerTicket(2L, "Order00002", "DemoCustomerTicket2", new Date()));
54 |
55 | List customerTickets = this.customerTicketRepository.getCustomerTicketByOrderNumber("Order00003");
56 | assertThat(customerTickets).size().isEqualTo(0);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerServiceTests.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.runner.RunWith;
5 | import org.mockito.Mockito;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.boot.test.mock.mockito.MockBean;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | import com.springcss.customer.client.OrderClient;
12 | import com.springcss.customer.client.OrderMapper;
13 | import com.springcss.customer.domain.CustomerTicket;
14 | import com.springcss.customer.domain.LocalAccount;
15 | import com.springcss.customer.repository.CustomerTicketRepository;
16 | import com.springcss.customer.repository.LocalAccountRepository;
17 | import com.springcss.customer.service.CustomerTicketService;
18 |
19 | import java.util.Date;
20 |
21 | import static org.assertj.core.api.Assertions.assertThat;
22 |
23 | @RunWith(SpringRunner.class)
24 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
25 | public class CustomerServiceTests {
26 |
27 | @MockBean
28 | private OrderClient orderClient;
29 |
30 | @MockBean
31 | private CustomerTicketRepository customerTicketRepository;
32 |
33 | @MockBean
34 | private LocalAccountRepository localAccountRepository;
35 |
36 | @Autowired
37 | private CustomerTicketService customerTicketService;
38 |
39 | @Test
40 | public void testGetCustomerTicketById() throws Exception {
41 | Long id = 1L;
42 |
43 | Mockito.when(customerTicketRepository.getOne(id)).thenReturn(new CustomerTicket(1L, 1L, "Order00001", "DemoCustomerTicket1", new Date()));
44 |
45 | CustomerTicket actual = customerTicketService.getCustomerTicketById(id);
46 |
47 | assertThat(actual).isNotNull();
48 | assertThat(actual.getOrderNumber()).isEqualTo("Order00001");
49 | }
50 |
51 | @Test
52 | public void testGenerateCustomerTicket() throws Exception {
53 | Long accountId = 100L;
54 | String orderNumber = "Order00001";
55 |
56 | Mockito.when(this.orderClient.getOrderByOrderNumber("Order00001"))
57 | .thenReturn(new OrderMapper(1L, orderNumber, "deliveryAddress"));
58 |
59 | Mockito.when(this.localAccountRepository.getOne(accountId))
60 | .thenReturn(new LocalAccount(100L, "accountCode", "accountName"));
61 |
62 | CustomerTicket actual = customerTicketService.generateCustomerTicket(accountId, orderNumber);
63 |
64 | assertThat(actual.getOrderNumber()).isEqualTo(orderNumber);
65 | }
66 | }
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/CustomerTicketTests.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 |
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | import com.springcss.customer.domain.CustomerTicket;
9 |
10 | import static org.assertj.core.api.Assertions.assertThat;
11 |
12 | @RunWith(SpringRunner.class)
13 | public class CustomerTicketTests {
14 |
15 | private static final String ORDER_NUMBER = "Order00001";
16 |
17 | @Test
18 | public void testOrderNumberIsExactly10Chars() throws Exception {
19 |
20 | CustomerTicket customerTicket = new CustomerTicket(100L, ORDER_NUMBER);
21 |
22 | assertThat(customerTicket.getOrderNumber().toString()).isEqualTo(ORDER_NUMBER);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/customer-service/src/test/java/com/springcss/customer/EnvironmentTests.java:
--------------------------------------------------------------------------------
1 | package com.springcss.customer;
2 |
3 | import org.junit.Test;
4 | import org.junit.Assert;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.core.env.Environment;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | @RunWith(SpringRunner.class)
12 | @SpringBootTest(properties = {" springcss.order.point = 10"})
13 | public class EnvironmentTests{
14 |
15 | @Autowired
16 | public Environment environment;
17 |
18 | @Test
19 | public void testEnvValue(){
20 | Assert.assertEquals(10, Integer.parseInt(environment.getProperty("springcss.order.point")));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/customer-service/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | #springcss.order.point = 10
--------------------------------------------------------------------------------
/message/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.springcss
8 | message
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | message
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-test
25 | test
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/message/src/main/java/com/springcss/message/AccountChangedEvent.java:
--------------------------------------------------------------------------------
1 | package com.springcss.message;
2 |
3 | import java.io.Serializable;
4 |
5 | public class AccountChangedEvent implements Serializable {
6 |
7 | private static final long serialVersionUID = 1L;
8 |
9 | //事件类型
10 | private String type;
11 | //事件所对应的操作
12 | private String operation;
13 | //事件对应的领域模型
14 | private AccountMessage accountMessage;
15 |
16 |
17 | public AccountChangedEvent() {
18 | super();
19 | }
20 |
21 | public AccountChangedEvent(String type, String operation, AccountMessage accountMessage) {
22 | super();
23 | this.type = type;
24 | this.operation = operation;
25 | this.accountMessage = accountMessage;
26 | }
27 |
28 | public String getType() {
29 | return type;
30 | }
31 |
32 | public void setType(String type) {
33 | this.type = type;
34 | }
35 |
36 | public String getOperation() {
37 | return operation;
38 | }
39 |
40 | public void setOperation(String operation) {
41 | this.operation = operation;
42 | }
43 |
44 | public AccountMessage getAccountMessage() {
45 | return accountMessage;
46 | }
47 |
48 | public void setAccountMessage(AccountMessage accountMessage) {
49 | this.accountMessage = accountMessage;
50 | }
51 | }
--------------------------------------------------------------------------------
/message/src/main/java/com/springcss/message/AccountChannels.java:
--------------------------------------------------------------------------------
1 | package com.springcss.message;
2 |
3 | public class AccountChannels {
4 |
5 | public static final String SPRINGCSS_ACCOUNT_TOPIC = "springcss.account.topic";
6 |
7 | public static final String SPRINGCSS_ACCOUNT_QUEUE = "springcss.account.queue";
8 | }
9 |
--------------------------------------------------------------------------------
/message/src/main/java/com/springcss/message/AccountMessage.java:
--------------------------------------------------------------------------------
1 | package com.springcss.message;
2 |
3 | import java.io.Serializable;
4 |
5 | public class AccountMessage implements Serializable {
6 |
7 | private static final long serialVersionUID = 1L;
8 |
9 | private Long id;
10 | private String accountCode;
11 | private String accountName;
12 |
13 | public AccountMessage() {
14 | super();
15 | }
16 |
17 | public AccountMessage(Long id, String accountCode, String accountName) {
18 | super();
19 | this.id = id;
20 | this.accountCode = accountCode;
21 | this.accountName = accountName;
22 | }
23 |
24 | public Long getId() {
25 | return id;
26 | }
27 | public void setId(Long id) {
28 | this.id = id;
29 | }
30 | public String getAccountCode() {
31 | return accountCode;
32 | }
33 | public void setAccountCode(String accountCode) {
34 | this.accountCode = accountCode;
35 | }
36 | public String getAccountName() {
37 | return accountName;
38 | }
39 | public void setAccountName(String accountName) {
40 | this.accountName = accountName;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/order-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.springcss
8 | order-service
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | Order Service
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.4.RELEASE
18 |
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-jdbc
25 |
26 |
27 | org.springframework.boot
28 | spring-boot-starter-data-jpa
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-web
34 |
35 |
36 | org.springframework.boot
37 | spring-boot-starter-actuator
38 |
39 |
40 |
41 | com.h2database
42 | h2
43 |
44 |
45 |
46 | mysql
47 | mysql-connector-java
48 |
49 |
50 |
51 | org.apache.commons
52 | commons-pool2
53 |
54 |
55 |
56 | de.codecentric
57 | spring-boot-admin-starter-client
58 | 2.2.3
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-starter-test
64 | test
65 |
66 |
67 |
68 |
69 |
70 |
71 | org.springframework.boot
72 | spring-boot-maven-plugin
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/OrderApplication.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class OrderApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(OrderApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/controller/JpaOrderController.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestBody;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | import com.springcss.order.domain.JpaOrder;
12 | import com.springcss.order.service.JpaOrderService;
13 |
14 | @RestController
15 | @RequestMapping(value="orders/jpa")
16 | public class JpaOrderController {
17 |
18 | @Autowired
19 | JpaOrderService jpaOrderService;
20 |
21 | @GetMapping(value = "/{orderId}")
22 | public JpaOrder getOrderById(@PathVariable Long orderId) {
23 |
24 | JpaOrder order = jpaOrderService.getOrderById(orderId);
25 | return order;
26 | }
27 |
28 | @GetMapping(value = "orderNumber/{orderNumber}")
29 | public JpaOrder getOrderByOrderNumber(@PathVariable String orderNumber) {
30 |
31 | // JpaOrder order = jpaOrderService.getOrderByOrderNumber(orderNumber);
32 | // JpaOrder order = jpaOrderService.getOrderByOrderNumberByExample(orderNumber);
33 | JpaOrder order = jpaOrderService.getOrderByOrderNumberBySpecification(orderNumber);
34 | return order;
35 | }
36 |
37 | @PostMapping(value = "")
38 | public JpaOrder addOrder(@RequestBody JpaOrder order) {
39 |
40 | JpaOrder result = jpaOrderService.addOrder(order);
41 | return result;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/controller/OrderController.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.controller;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.GetMapping;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestBody;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | import com.springcss.order.domain.Order;
12 | import com.springcss.order.service.OrderService;
13 |
14 | @RestController
15 | @RequestMapping(value="orders")
16 | public class OrderController {
17 |
18 | @Autowired
19 | OrderService orderService;
20 |
21 | @GetMapping(value = "/{orderId}")
22 | public Order getOrderById(@PathVariable Long orderId) {
23 |
24 | Order order = orderService.getOrderById(orderId);
25 | return order;
26 | }
27 |
28 | @GetMapping(value = "orderNumber/{orderNumber}")
29 | public Order getOrderByOrderNumber(@PathVariable String orderNumber) {
30 |
31 | Order order = orderService.getOrderDetailByOrderNumber(orderNumber);
32 | return order;
33 | }
34 |
35 | @PostMapping(value = "")
36 | public Order addOrder(@RequestBody Order order) {
37 |
38 | Order result = orderService.addOrder(order);
39 | return result;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/domain/Goods.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.domain;
2 |
3 | public class Goods {
4 | private Long id;
5 | private String goodsCode;
6 | private String goodsName;
7 | private Double price;
8 |
9 | public Goods() {
10 | super();
11 | }
12 |
13 | public Goods(Long id, String goodsCode, String goodsName, Double price) {
14 | super();
15 | this.id = id;
16 | this.goodsCode = goodsCode;
17 | this.goodsName = goodsName;
18 | this.price = price;
19 | }
20 |
21 | public Long getId() {
22 | return id;
23 | }
24 | public void setId(Long id) {
25 | this.id = id;
26 | }
27 | public String getGoodsCode() {
28 | return goodsCode;
29 | }
30 | public void setGoodsCode(String goodsCode) {
31 | this.goodsCode = goodsCode;
32 | }
33 | public String getGoodsName() {
34 | return goodsName;
35 | }
36 | public void setGoodsName(String goodsName) {
37 | this.goodsName = goodsName;
38 | }
39 | public Double getPrice() {
40 | return price;
41 | }
42 | public void setPrice(Double price) {
43 | this.price = price;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/domain/JpaGoods.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.domain;
2 |
3 | import javax.persistence.Entity;
4 | import javax.persistence.GeneratedValue;
5 | import javax.persistence.GenerationType;
6 | import javax.persistence.Id;
7 | import javax.persistence.Table;
8 |
9 | @Entity
10 | @Table(name="goods")
11 | public class JpaGoods {
12 |
13 | @Id
14 | @GeneratedValue(strategy = GenerationType.IDENTITY)
15 | private Long id;
16 | private String goodsCode;
17 | private String goodsName;
18 | private Float price;
19 |
20 | public Long getId() {
21 | return id;
22 | }
23 | public void setId(Long id) {
24 | this.id = id;
25 | }
26 | public String getGoodsCode() {
27 | return goodsCode;
28 | }
29 | public void setGoodsCode(String goodsCode) {
30 | this.goodsCode = goodsCode;
31 | }
32 | public String getGoodsName() {
33 | return goodsName;
34 | }
35 | public void setGoodsName(String goodsName) {
36 | this.goodsName = goodsName;
37 | }
38 | public Float getPrice() {
39 | return price;
40 | }
41 | public void setPrice(Float price) {
42 | this.price = price;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/domain/JpaOrder.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.domain;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import javax.persistence.Entity;
8 | import javax.persistence.GeneratedValue;
9 | import javax.persistence.GenerationType;
10 | import javax.persistence.Id;
11 | import javax.persistence.JoinTable;
12 | import javax.persistence.JoinColumn;
13 | import javax.persistence.ManyToMany;
14 | import javax.persistence.NamedQueries;
15 | import javax.persistence.NamedQuery;
16 | import javax.persistence.Table;
17 |
18 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
19 |
20 | @Entity
21 | @Table(name = "`order`")
22 | @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
23 | @NamedQueries({ @NamedQuery(name = "getOrderByOrderNumberWithQuery", query = "select o from JpaOrder o where o.orderNumber = ?1") })
24 | public class JpaOrder implements Serializable {
25 | private static final long serialVersionUID = 1L;
26 |
27 | @Id
28 | @GeneratedValue(strategy = GenerationType.IDENTITY)
29 | private Long id;
30 | private String orderNumber;
31 | private String deliveryAddress;
32 |
33 | @ManyToMany(targetEntity = JpaGoods.class)
34 | @JoinTable(name = "order_goods", joinColumns = @JoinColumn(name = "order_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "goods_id", referencedColumnName = "id"))
35 | private List goods = new ArrayList<>();
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 getOrderNumber() {
46 | return orderNumber;
47 | }
48 |
49 | public void setOrderNumber(String orderNumber) {
50 | this.orderNumber = orderNumber;
51 | }
52 |
53 | public String getDeliveryAddress() {
54 | return deliveryAddress;
55 | }
56 |
57 | public void setDeliveryAddress(String deliveryAddress) {
58 | this.deliveryAddress = deliveryAddress;
59 | }
60 |
61 | public List getGoods() {
62 | return goods;
63 | }
64 |
65 | public void setGoods(List goods) {
66 | this.goods = goods;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/domain/Order.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.domain;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class Order{
7 |
8 | private Long id;
9 | private String orderNumber;
10 | private String deliveryAddress;
11 | private List goodsList;
12 |
13 | public Order() {
14 | super();
15 | }
16 |
17 | public Order(Long id, String orderNumber, String deliveryAddress) {
18 | super();
19 | this.id = id;
20 | this.orderNumber = orderNumber;
21 | this.deliveryAddress = deliveryAddress;
22 | this.goodsList = new ArrayList();
23 | }
24 |
25 | public void addGoods(Goods goods) {
26 | goodsList.add(goods);
27 | }
28 |
29 | public Long getId() {
30 | return id;
31 | }
32 | public void setId(Long id) {
33 | this.id = id;
34 | }
35 | public String getOrderNumber() {
36 | return orderNumber;
37 | }
38 | public void setOrderNumber(String orderNumber) {
39 | this.orderNumber = orderNumber;
40 | }
41 | public String getDeliveryAddress() {
42 | return deliveryAddress;
43 | }
44 | public void setDeliveryAddress(String deliveryAddress) {
45 | this.deliveryAddress = deliveryAddress;
46 | }
47 |
48 | public List getGoods() {
49 | return goodsList;
50 | }
51 |
52 | public void setGoods(List goods) {
53 | this.goodsList = goods;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/OrderJdbcRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository;
2 |
3 | import java.sql.Connection;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Statement;
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.dao.DataAccessException;
15 | import org.springframework.jdbc.core.JdbcTemplate;
16 | import org.springframework.jdbc.core.PreparedStatementCreator;
17 | import org.springframework.jdbc.core.ResultSetExtractor;
18 | import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
19 | import org.springframework.jdbc.support.GeneratedKeyHolder;
20 | import org.springframework.jdbc.support.KeyHolder;
21 | import org.springframework.stereotype.Repository;
22 |
23 | import com.springcss.order.domain.Goods;
24 | import com.springcss.order.domain.Order;
25 |
26 | @Repository("orderJdbcRepository")
27 | public class OrderJdbcRepository implements OrderRepository {
28 |
29 | private JdbcTemplate jdbcTemplate;
30 |
31 | private SimpleJdbcInsert orderInserter;
32 | private SimpleJdbcInsert orderGoodsInserter;
33 |
34 | @Autowired
35 | public OrderJdbcRepository(JdbcTemplate jdbcTemplate) {
36 | this.jdbcTemplate = jdbcTemplate;
37 | this.orderInserter = new SimpleJdbcInsert(jdbcTemplate).withTableName("`order`").usingGeneratedKeyColumns("id");
38 | this.orderGoodsInserter = new SimpleJdbcInsert(jdbcTemplate).withTableName("order_goods");
39 | }
40 |
41 | @Override
42 | public Order addOrder(Order order) {
43 | // return addOrderWithJdbcTemplate(order);
44 |
45 | return addOrderDetailWithSimpleJdbcInsert(order);
46 | }
47 |
48 | @Override
49 | public Order getOrderById(Long orderId) {
50 | Order order = jdbcTemplate.queryForObject("select id, order_number, delivery_address from `order` where id=?",
51 | this::mapRowToOrder, orderId);
52 |
53 | return order;
54 | }
55 |
56 | @Override
57 | public Order getOrderDetailByOrderNumber(String orderNumber) {
58 | //获取Order基础信息
59 | Order order = jdbcTemplate.queryForObject(
60 | "select id, order_number, delivery_address from `order` where order_number=?", this::mapRowToOrder,
61 | orderNumber);
62 |
63 | if (order == null)
64 | return order;
65 |
66 | //获取Order与Goods之间的关联关系,找到给Order中的所有GoodsId
67 | Long orderId = order.getId();
68 | List goodsIds = jdbcTemplate.query("select order_id, goods_id from order_goods where order_id=?",
69 | new ResultSetExtractor>() {
70 | public List extractData(ResultSet rs) throws SQLException, DataAccessException {
71 | List list = new ArrayList();
72 | while (rs.next()) {
73 | list.add(rs.getLong("goods_id"));
74 | }
75 | return list;
76 | }
77 | }, orderId);
78 |
79 | //根据GoodsId分别获取Goods信息并填充到Order对象中
80 | for (Long goodsId : goodsIds) {
81 | Goods goods = getGoodsById(goodsId);
82 | order.addGoods(goods);
83 | }
84 |
85 | return order;
86 | }
87 |
88 | private Goods getGoodsById(Long goodsId) {
89 | return jdbcTemplate.queryForObject("select id, goods_code, goods_name, price from goods where id=?",
90 | this::mapRowToGoods, goodsId);
91 | }
92 |
93 | private Goods mapRowToGoods(ResultSet rs, int rowNum) throws SQLException {
94 | return new Goods(rs.getLong("id"), rs.getString("goods_code"), rs.getString("goods_name"),
95 | rs.getDouble("price"));
96 | }
97 |
98 | private Order mapRowToOrder(ResultSet rs, int rowNum) throws SQLException {
99 | return new Order(rs.getLong("id"), rs.getString("order_number"), rs.getString("delivery_address"));
100 | }
101 |
102 | // addOrderDetailWithJdbcTemplate
103 | private Order addOrderDetailWithJdbcTemplate(Order order) {
104 | //插入Order基础信息
105 | Long orderId = saveOrderWithJdbcTemplate(order);
106 |
107 | order.setId(orderId);
108 |
109 | //插入Order与Goods的对应关系
110 | List goodsList = order.getGoods();
111 | for (Goods goods : goodsList) {
112 | saveGoodsToOrderWithJdbcTemplate(goods, orderId);
113 | }
114 |
115 | return order;
116 | }
117 |
118 | private Long saveOrderWithJdbcTemplate(Order order) {
119 |
120 | PreparedStatementCreator psc = new PreparedStatementCreator() {
121 | @Override
122 | public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
123 | PreparedStatement ps = con.prepareStatement(
124 | "insert into `order` (order_number, delivery_address) values (?, ?)",
125 | Statement.RETURN_GENERATED_KEYS);
126 | ps.setString(1, order.getOrderNumber());
127 | ps.setString(2, order.getDeliveryAddress());
128 | return ps;
129 | }
130 | };
131 |
132 | KeyHolder keyHolder = new GeneratedKeyHolder();
133 | jdbcTemplate.update(psc, keyHolder);
134 |
135 | return keyHolder.getKey().longValue();
136 | }
137 |
138 | private void saveGoodsToOrderWithJdbcTemplate(Goods goods, long orderId) {
139 | jdbcTemplate.update("insert into order_goods (order_id, goods_id) " + "values (?, ?)", orderId, goods.getId());
140 | }
141 |
142 | // addOrderDetailWithSimpleJdbcInsert
143 | private Order addOrderDetailWithSimpleJdbcInsert(Order order) {
144 | //插入Order基础信息
145 | Long orderId = saveOrderWithSimpleJdbcInsert(order);
146 |
147 | order.setId(orderId);
148 |
149 | //插入Order与Goods的对应关系
150 | List goodsList = order.getGoods();
151 | for (Goods goods : goodsList) {
152 | saveGoodsToOrderWithSimpleJdbcInsert(goods, orderId);
153 | }
154 |
155 | return order;
156 | }
157 |
158 | private Long saveOrderWithSimpleJdbcInsert(Order order) {
159 | Map values = new HashMap();
160 | values.put("order_number", order.getOrderNumber());
161 | values.put("delivery_address", order.getDeliveryAddress());
162 |
163 | Long orderId = orderInserter.executeAndReturnKey(values).longValue();
164 | return orderId;
165 | }
166 |
167 | private void saveGoodsToOrderWithSimpleJdbcInsert(Goods goods, long orderId) {
168 | Map values = new HashMap<>();
169 | values.put("order_id", orderId);
170 | values.put("goods_id", goods.getId());
171 | orderGoodsInserter.execute(values);
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/OrderJpaRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
5 | import org.springframework.data.jpa.repository.Query;
6 | import org.springframework.data.repository.query.QueryByExampleExecutor;
7 | import org.springframework.stereotype.Repository;
8 |
9 | import com.springcss.order.domain.JpaOrder;
10 |
11 | @Repository("orderJpaRepository")
12 | public interface OrderJpaRepository extends JpaRepository,
13 | JpaSpecificationExecutor, QueryByExampleExecutor {
14 |
15 | @Query("select o from JpaOrder o where o.orderNumber = ?1")
16 | JpaOrder getOrderByOrderNumberWithQuery(String orderNumber);
17 |
18 | JpaOrder getOrderByOrderNumber(String orderNumber);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/OrderRawJdbcRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository;
2 |
3 | import java.sql.Connection;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 |
8 | import javax.sql.DataSource;
9 |
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Repository;
12 |
13 | import com.springcss.order.domain.Order;
14 |
15 | @Repository("orderRawJdbcRepository")
16 | public class OrderRawJdbcRepository implements OrderRepository {
17 |
18 | @Autowired
19 | private DataSource dataSource;
20 |
21 | @Override
22 | public Order addOrder(Order order) {
23 | // 不做实现
24 | return null;
25 | }
26 |
27 | @Override
28 | public Order getOrderById(Long orderId) {
29 |
30 | Connection connection = null;
31 | PreparedStatement statement = null;
32 | ResultSet resultSet = null;
33 | try {
34 | connection = dataSource.getConnection();
35 | statement = connection.prepareStatement("select id, order_number, delivery_address from `order` where id=?");
36 | statement.setLong(1, orderId);
37 | resultSet = statement.executeQuery();
38 | Order order = null;
39 | if (resultSet.next()) {
40 | order = new Order(resultSet.getLong("id"), resultSet.getString("order_number"),
41 | resultSet.getString("delivery_address"));
42 | }
43 | return order;
44 | } catch (SQLException e) {
45 | System.out.print(e);
46 | } finally {
47 | if (resultSet != null) {
48 | try {
49 | resultSet.close();
50 | } catch (SQLException e) {
51 | }
52 | }
53 | if (statement != null) {
54 | try {
55 | statement.close();
56 | } catch (SQLException e) {
57 | }
58 | }
59 | if (connection != null) {
60 | try {
61 | connection.close();
62 | } catch (SQLException e) {
63 | }
64 | }
65 | }
66 | return null;
67 | }
68 |
69 | @Override
70 | public Order getOrderDetailByOrderNumber(String orderNumber) {
71 | // 不做实现
72 | return null;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/OrderRepository.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository;
2 |
3 | import com.springcss.order.domain.Order;
4 |
5 | public interface OrderRepository {
6 |
7 | Order addOrder(Order order);
8 |
9 | Order getOrderById(Long orderId);
10 |
11 | Order getOrderDetailByOrderNumber(String orderNumber);
12 | }
13 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/AbstractJdbcTemplate.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.sql.Connection;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Statement;
8 |
9 | import javax.sql.DataSource;
10 |
11 | import org.springframework.beans.factory.annotation.Autowired;
12 |
13 | import com.springcss.order.domain.Order;
14 |
15 | public abstract class AbstractJdbcTemplate {
16 |
17 | @Autowired
18 | private DataSource dataSource;
19 |
20 | public final Object execute(String sql){
21 | Connection connection = null;
22 | Statement statement = null;
23 | ResultSet resultSet = null;
24 | try {
25 | connection = dataSource.getConnection();
26 | statement = connection.createStatement();
27 | resultSet = statement.executeQuery(sql);
28 | Object object = handleResultSet(resultSet);
29 | return object;
30 | } catch (SQLException e) {
31 | System.out.print(e);
32 | } finally {
33 | if (resultSet != null) {
34 | try {
35 | resultSet.close();
36 | } catch (SQLException e) {
37 | }
38 | }
39 | if (statement != null) {
40 | try {
41 | statement.close();
42 | } catch (SQLException e) {
43 | }
44 | }
45 | if (connection != null) {
46 | try {
47 | connection.close();
48 | } catch (SQLException e) {
49 | }
50 | }
51 | }
52 | return null;
53 | }
54 |
55 | protected abstract Object handleResultSet(ResultSet rs) throws SQLException;
56 | }
57 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/AbstractJdbcTemplateTest.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.util.List;
4 |
5 | import com.springcss.order.domain.Order;
6 |
7 | public class AbstractJdbcTemplateTest {
8 |
9 | @SuppressWarnings("unchecked")
10 | public void test() {
11 | AbstractJdbcTemplate jdbcTemplate = new OrderJdbcTemplate();
12 | List orders = (List) jdbcTemplate.execute("select * from Order");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/CallbackJdbcTemplate.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.sql.Connection;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Statement;
8 |
9 | import javax.sql.DataSource;
10 |
11 | import org.springframework.beans.factory.annotation.Autowired;
12 |
13 | import com.springcss.order.domain.Order;
14 |
15 | public class CallbackJdbcTemplate {
16 |
17 | @Autowired
18 | private DataSource dataSource;
19 |
20 | public final Object execute(StatementCallback callback){
21 | Connection connection = null;
22 | Statement statement = null;
23 | ResultSet resultSet = null;
24 | try {
25 | connection = dataSource.getConnection();
26 | statement = connection.createStatement();
27 | Object object = callback.handleStatement(statement);
28 | return object;
29 | } catch (SQLException e) {
30 | System.out.print(e);
31 | } finally {
32 | if (resultSet != null) {
33 | try {
34 | resultSet.close();
35 | } catch (SQLException e) {
36 | }
37 | }
38 | if (statement != null) {
39 | try {
40 | statement.close();
41 | } catch (SQLException e) {
42 | }
43 | }
44 | if (connection != null) {
45 | try {
46 | connection.close();
47 | } catch (SQLException e) {
48 | }
49 | }
50 | }
51 | return null;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/CallbackJdbcTemplateTest.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.sql.ResultSet;
4 | import java.sql.SQLException;
5 | import java.sql.Statement;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import com.springcss.order.domain.Order;
10 |
11 | public class CallbackJdbcTemplateTest {
12 |
13 | public Object queryOrder(final String sql) {
14 |
15 | class OrderStatementCallback implements StatementCallback {
16 |
17 | public Object handleStatement(Statement statement) throws SQLException {
18 | ResultSet rs = statement.executeQuery(sql);
19 | List orders = new ArrayList();
20 | while (rs.next()) {
21 | Order order = new Order(rs.getLong("id"), rs.getString("order_number"),
22 | rs.getString("delivery_address"));
23 | orders.add(order);
24 | }
25 |
26 | return orders;
27 | }
28 | }
29 |
30 | CallbackJdbcTemplate jdbcTemplate = new CallbackJdbcTemplate();
31 | return jdbcTemplate.execute(new OrderStatementCallback());
32 | }
33 |
34 | public Object queryOrder2(final String sql) {
35 |
36 | CallbackJdbcTemplate jdbcTemplate = new CallbackJdbcTemplate();
37 | return jdbcTemplate.execute(new StatementCallback() {
38 |
39 | public Object handleStatement(Statement statement) throws SQLException {
40 | ResultSet rs = statement.executeQuery(sql);
41 | List orders = new ArrayList();
42 | while (rs.next()) {
43 | Order order = new Order(rs.getLong("id"), rs.getString("order_number"),
44 | rs.getString("delivery_address"));
45 | orders.add(order);
46 | }
47 |
48 | return orders;
49 | }
50 | });
51 | }
52 |
53 |
54 | @SuppressWarnings("unchecked")
55 | public void test() {
56 | List orders = (List) queryOrder("select * from Order");
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/OrderJdbcTemplate.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.sql.ResultSet;
4 | import java.sql.SQLException;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import com.springcss.order.domain.Order;
9 |
10 | public class OrderJdbcTemplate extends AbstractJdbcTemplate {
11 |
12 | @Override
13 | protected Object handleResultSet(ResultSet rs) throws SQLException {
14 |
15 | List orders = new ArrayList();
16 | while (rs.next()) {
17 | Order order = new Order(rs.getLong("id"), rs.getString("order_number"), rs.getString("delivery_address"));
18 | orders.add(order);
19 | }
20 | return orders;
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/repository/jdbctemplate/StatementCallback.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.repository.jdbctemplate;
2 |
3 | import java.sql.SQLException;
4 | import java.sql.Statement;
5 |
6 | public interface StatementCallback {
7 |
8 | Object handleStatement(Statement statement) throws SQLException;
9 | }
10 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/springcss/order/service/JpaOrderService.java:
--------------------------------------------------------------------------------
1 | package com.springcss.order.service;
2 |
3 | import javax.persistence.criteria.CriteriaBuilder;
4 | import javax.persistence.criteria.CriteriaQuery;
5 | import javax.persistence.criteria.Path;
6 | import javax.persistence.criteria.Predicate;
7 | import javax.persistence.criteria.Root;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.data.domain.Example;
11 | import org.springframework.data.domain.ExampleMatcher;
12 | import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers;
13 | import org.springframework.data.jpa.domain.Specification;
14 | import org.springframework.stereotype.Service;
15 |
16 | import com.springcss.order.domain.JpaOrder;
17 | import com.springcss.order.repository.OrderJpaRepository;
18 |
19 | @Service
20 | public class JpaOrderService {
21 |
22 | @Autowired
23 | private OrderJpaRepository orderJpaRepository;
24 |
25 | public JpaOrder getOrderById(Long orderId) {
26 |
27 | return orderJpaRepository.getOne(orderId);
28 | }
29 |
30 | public JpaOrder getOrderByOrderNumber(String orderNumber) {
31 |
32 | return orderJpaRepository.getOrderByOrderNumber(orderNumber);
33 | }
34 |
35 | public JpaOrder getOrderByOrderNumberWithQuery(String orderNumber) {
36 |
37 | return orderJpaRepository.getOrderByOrderNumberWithQuery(orderNumber);
38 | }
39 |
40 | public JpaOrder getOrderByOrderNumberByExample(String orderNumber) {
41 | JpaOrder order = new JpaOrder();
42 | order.setOrderNumber(orderNumber);
43 |
44 | ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreCase()
45 | .withMatcher("orderNumber", GenericPropertyMatchers.exact()).withIncludeNullValues();
46 |
47 | Example example = Example.of(order, matcher);
48 |
49 | return orderJpaRepository.findOne(example).orElse(new JpaOrder());
50 | }
51 |
52 | public JpaOrder getOrderByOrderNumberBySpecification(String orderNumber) {
53 | JpaOrder order = new JpaOrder();
54 | order.setOrderNumber(orderNumber);
55 |
56 | @SuppressWarnings("serial")
57 | Specification spec = new Specification() {
58 | @Override
59 | public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder cb) {
60 | Path