feat: integrated example local version initialized (#2711)
* Integrated example local version business and docs initialized * polish code * add frontend module and refactor distributed tx scenarios * resolving front-end cross-origin * rocketmq frontend * sentinel frontend * feat: localized deployment for integrated-examplepull/2825/head
parent
de3cfb10cb
commit
bb5c6d0e92
@ -1,376 +1,376 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.3.5.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.3.5.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba</artifactId>
|
||||
<version>${revision}</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Alibaba</name>
|
||||
<description>Spring Cloud Alibaba</description>
|
||||
<url>https://github.com/alibaba/spring-cloud-alibaba</url>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba</artifactId>
|
||||
<version>${revision}</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Alibaba</name>
|
||||
<description>Spring Cloud Alibaba</description>
|
||||
<url>https://github.com/alibaba/spring-cloud-alibaba</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/alibaba/spring-cloud-alibaba</url>
|
||||
<connection>
|
||||
scm:git:git://github.com/alibaba/spring-cloud-alibaba.git
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:git:ssh://git@github.com/alibaba/spring-cloud-alibaba.git
|
||||
</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
<scm>
|
||||
<url>https://github.com/alibaba/spring-cloud-alibaba</url>
|
||||
<connection>
|
||||
scm:git:git://github.com/alibaba/spring-cloud-alibaba.git
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:git:ssh://git@github.com/alibaba/spring-cloud-alibaba.git
|
||||
</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>xiaojing</name>
|
||||
<email>flystar32@163.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>Jim Fang</name>
|
||||
<email>fangjian0423@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/fangjian0423</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>xiaolongzuo</name>
|
||||
<email>150349407@qq.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>hengyunabc</name>
|
||||
<email>hengyunabc@gmail.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mercyblitz</id>
|
||||
<name>Mercy Ma</name>
|
||||
<email>mercyblitz@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/mercyblitz</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>yunzheng</name>
|
||||
<email>yunzheng1228@gmail.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>theonefx</id>
|
||||
<name>theonefx</name>
|
||||
<email>chenxilzx1@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/theonefx</url>
|
||||
</developer>
|
||||
</developers>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>xiaojing</name>
|
||||
<email>flystar32@163.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>Jim Fang</name>
|
||||
<email>fangjian0423@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/fangjian0423</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>xiaolongzuo</name>
|
||||
<email>150349407@qq.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>hengyunabc</name>
|
||||
<email>hengyunabc@gmail.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mercyblitz</id>
|
||||
<name>Mercy Ma</name>
|
||||
<email>mercyblitz@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/mercyblitz</url>
|
||||
</developer>
|
||||
<developer>
|
||||
<name>yunzheng</name>
|
||||
<email>yunzheng1228@gmail.com</email>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>theonefx</id>
|
||||
<name>theonefx</name>
|
||||
<email>chenxilzx1@gmail.com</email>
|
||||
<organization>Alibaba</organization>
|
||||
<url>https://github.com/theonefx</url>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<!-- Project revision -->
|
||||
<revision>2.2.9-SNAPSHOT</revision>
|
||||
<properties>
|
||||
<!-- Project revision -->
|
||||
<revision>2.2.9-SNAPSHOT</revision>
|
||||
|
||||
<!-- Spring Cloud -->
|
||||
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
|
||||
<!-- Spring Cloud -->
|
||||
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
|
||||
|
||||
<!-- Apache Dubbo -->
|
||||
<dubbo.version>2.7.15</dubbo.version>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
<!-- Apache Dubbo -->
|
||||
<dubbo.version>2.7.15</dubbo.version>
|
||||
<curator.version>4.0.1</curator.version>
|
||||
|
||||
<!-- Apache RocketMQ -->
|
||||
<rocketmq.starter.version>2.0.4</rocketmq.starter.version>
|
||||
<rocketmq.version>4.9.3</rocketmq.version>
|
||||
<!-- Apache RocketMQ -->
|
||||
<rocketmq.starter.version>2.0.4</rocketmq.starter.version>
|
||||
<rocketmq.version>4.9.3</rocketmq.version>
|
||||
|
||||
<!-- Maven Plugin Versions -->
|
||||
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
||||
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
|
||||
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
|
||||
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
|
||||
<flatten-maven-plugin.version>1.1.0</flatten-maven-plugin.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<jacoco.version>0.8.3</jacoco.version>
|
||||
</properties>
|
||||
<!-- Maven Plugin Versions -->
|
||||
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
||||
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
|
||||
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
|
||||
<maven-source-plugin.version>2.2.1</maven-source-plugin.version>
|
||||
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
|
||||
<maven-gpg-plugin.version>1.6</maven-gpg-plugin.version>
|
||||
<flatten-maven-plugin.version>1.1.0</flatten-maven-plugin.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<jacoco.version>0.8.3</jacoco.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-alibaba-dependencies</module>
|
||||
<module>spring-cloud-alibaba-examples</module>
|
||||
<module>spring-cloud-alibaba-docs</module>
|
||||
<module>spring-cloud-alibaba-starters</module>
|
||||
<module>spring-cloud-alibaba-coverage</module>
|
||||
</modules>
|
||||
<modules>
|
||||
<module>spring-cloud-alibaba-dependencies</module>
|
||||
<module>spring-cloud-alibaba-examples</module>
|
||||
<module>spring-cloud-alibaba-docs</module>
|
||||
<module>spring-cloud-alibaba-starters</module>
|
||||
<module>spring-cloud-alibaba-coverage</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- Spring Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring.cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring.cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Dubbo Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-bom</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- Dubbo Dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-bom</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-starter</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-actuator</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-spring-boot-actuator</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-client</artifactId>
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-acl</artifactId>
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-client</artifactId>
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-acl</artifactId>
|
||||
<version>${rocketmq.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<configuration>
|
||||
<useProjectReferences>false</useProjectReferences>
|
||||
<additionalConfig>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.ui.prefs</name>
|
||||
<location>
|
||||
${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.ui.prefs
|
||||
</location>
|
||||
</file>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.core.prefs</name>
|
||||
<location>
|
||||
${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.core.prefs
|
||||
</location>
|
||||
</file>
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>checkstyle-validation</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Checkstyle rules inherited from spring-cloud-build -->
|
||||
<suppressionsLocation>
|
||||
${session.executionRootDirectory}/eclipse/checkstyle-suppressions.xml
|
||||
</suppressionsLocation>
|
||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<parameters>true</parameters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<reuseForks>false</reuseForks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>flatten-maven-plugin</artifactId>
|
||||
<version>${flatten-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<updatePomFile>true</updatePomFile>
|
||||
<flattenMode>resolveCiFriendliesOnly</flattenMode>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>flatten</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>flatten</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>flatten.clean</id>
|
||||
<phase>clean</phase>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>${jacoco.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<configuration>
|
||||
<useProjectReferences>false</useProjectReferences>
|
||||
<additionalConfig>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.ui.prefs</name>
|
||||
<location>
|
||||
${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.ui.prefs
|
||||
</location>
|
||||
</file>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.core.prefs</name>
|
||||
<location>
|
||||
${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.core.prefs
|
||||
</location>
|
||||
</file>
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>checkstyle-validation</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- Checkstyle rules inherited from spring-cloud-build -->
|
||||
<suppressionsLocation>
|
||||
${maven.multiModuleProjectDirectory}/eclipse/checkstyle-suppressions.xml
|
||||
</suppressionsLocation>
|
||||
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<parameters>true</parameters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<reuseForks>false</reuseForks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>flatten-maven-plugin</artifactId>
|
||||
<version>${flatten-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<updatePomFile>true</updatePomFile>
|
||||
<flattenMode>resolveCiFriendliesOnly</flattenMode>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>flatten</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>flatten</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>flatten.clean</id>
|
||||
<phase>clean</phase>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>${maven-source-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>${maven-source-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>${maven-gpg-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>${maven-gpg-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,10 @@
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: 123456
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
mybatis:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/integrated_account?useSSL=false&characterEncoding=utf8
|
@ -0,0 +1,18 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/integrated_praise?useSSL=false&characterEncoding=utf8
|
||||
cloud:
|
||||
stream:
|
||||
bindings:
|
||||
praise-input:
|
||||
destination: PRAISE-TOPIC-01
|
||||
content-type: application/json
|
||||
group: praise-consumer-group-PRAISE-TOPIC-01
|
||||
rocketmq:
|
||||
binder:
|
||||
name-server: localhost:9876
|
||||
bindings:
|
||||
praise-input:
|
||||
consumer:
|
||||
pullInterval: 4000
|
||||
pullBatchSize: 4
|
@ -0,0 +1,28 @@
|
||||
spring:
|
||||
cloud:
|
||||
gateway:
|
||||
routes:
|
||||
- id: placeOrder
|
||||
uri: lb://integrated-order
|
||||
predicates:
|
||||
- Path=/order/create
|
||||
- id: queryStorage
|
||||
uri: lb://integrated-storage
|
||||
predicates:
|
||||
- Path=/storage/
|
||||
- id: queryAccount
|
||||
uri: lb://integrated-account
|
||||
predicates:
|
||||
- Path=/account/
|
||||
- id: praiseItemRocketMQ
|
||||
uri: lb://integrated-provider
|
||||
predicates:
|
||||
- Path=/praise/rocketmq
|
||||
- id: praiseItemSentinel
|
||||
uri: lb://integrated-provider
|
||||
predicates:
|
||||
- Path=/praise/sentinel
|
||||
- id: queryPraise
|
||||
uri: lb://integrated-consumer
|
||||
predicates:
|
||||
- Path=/praise/query
|
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/integrated_order?useSSL=false&characterEncoding=utf8
|
@ -0,0 +1,14 @@
|
||||
spring:
|
||||
cloud:
|
||||
stream:
|
||||
bindings:
|
||||
praise-output:
|
||||
destination: PRAISE-TOPIC-01
|
||||
content-type: application/json
|
||||
rocketmq:
|
||||
binder:
|
||||
name-server: localhost:9876
|
||||
bindings:
|
||||
praise-output:
|
||||
producer:
|
||||
group: test
|
@ -0,0 +1,3 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://localhost:3306/integrated_storage?useSSL=false&characterEncoding=utf8
|
@ -0,0 +1,2 @@
|
||||
# Spring Cloud Alibaba Containerized Deployment Best Practices | Docker-Compose Container Edition
|
||||
Under Construction.....
|
@ -0,0 +1,191 @@
|
||||
## Spring Cloud Alibaba Containerized Deployment Best Practices | Local Deployment Version
|
||||
|
||||
## Preparation
|
||||
|
||||
### Environment declaration
|
||||
|
||||
Before running the local example, you need to ensure that the following base environment is available locally. If you do not have a current environment locally, the following step-by-step build will demonstrate the build process.
|
||||
|
||||
- Nacos server
|
||||
- Seata server
|
||||
- RocketMQ server
|
||||
- MySQL server
|
||||
|
||||
### Component Service Versions
|
||||
|
||||
To download and unpack the component versions of this project, please go to the release pages of the respective communities.
|
||||
|
||||
- [Nacos: version 2.1.0](https://github.com/alibaba/nacos/releases)
|
||||
- [Seata: version 1.5.1](https://github.com/seata/seata/releases)
|
||||
- [RocketMQ: version 4.9.4](https://github.com/apache/rocketmq/releases)
|
||||
- MySQL: version 5.7
|
||||
|
||||
### Database configuration
|
||||
|
||||
The following starts the local environment build preparation, before the database configuration starts, please make sure that the MySQL server is turned on.
|
||||
|
||||
#### Initializing Business Tables
|
||||
|
||||
For the first scenario, the orders, accounts and inventory microservices all need their own databases, while the second scenario simulating likes also needs a database to store the likes information.
|
||||
|
||||
Run the sql script `spring-cloud-alibaba-examples/integrated-example/sql/init.sql` to create the environment required for the business and the Seata-related tables in one click.
|
||||
|
||||
### Nacos configuration
|
||||
|
||||
Now that the database services are configured, you need to configure the Nacos configuration centre with all the microservice configuration files.
|
||||
|
||||
#### Nacos startup
|
||||
|
||||
For the purpose of this example, Nacos is started in ``standalone'' mode. Go to the Nacos unpacked directory and execute the following command.
|
||||
|
||||
```sh
|
||||
#Linux/Mac environment
|
||||
sh bin/startup.sh -m standalone
|
||||
#If you are in Ubuntu and the above command gives you an error saying [[symbol not found, you can run the following command
|
||||
bash bin/startup.sh -m standalone
|
||||
#Win environment
|
||||
. \bin\startup.cmd -m standalone
|
||||
```
|
||||
|
||||
#### Adding configuration files
|
||||
|
||||
Before bulk importing the configuration, change the datasource configuration (username and password) in `integrated-example/config/datasource-config.yaml`.
|
||||
|
||||
Afterwards, run `spring-cloud-alibaba-examples/integrated-example/scripts/nacos-config-quick.sh` to complete the one-click import of all microservice configurations.
|
||||
|
||||
### Seata configuration
|
||||
|
||||
Once the Nacos service registry and configuration centre have been deployed, here is the configuration of the Seata server.
|
||||
|
||||
Seata's db mode requires additional configuration of the database information and modification of the Seata Server configuration file, which has been merged in the new version compared to the old one.
|
||||
|
||||
#### Start Seata Server
|
||||
|
||||
Go to the seata directory after the release and execute the following command.
|
||||
|
||||
```sh
|
||||
#Linux/Mac environment
|
||||
sh . /bin/seata-server.sh
|
||||
#Win environment
|
||||
bin\seata-server.bat
|
||||
```
|
||||
|
||||
### RocketMQ configuration
|
||||
|
||||
Once the Seata service is started, you can start the RocketMQ NameServer and Broker services.
|
||||
|
||||
Go to the unpacked rocketmq directory after the release and execute the following command.
|
||||
|
||||
#### Start the NameServer
|
||||
|
||||
```sh
|
||||
#Linux/Mac environment
|
||||
sh bin/mqnamesrv
|
||||
#Win environment
|
||||
. \bin\mqnamesrv.cmd
|
||||
```
|
||||
|
||||
#### Start Broker
|
||||
|
||||
```sh
|
||||
#Linux/Mac environment
|
||||
sh bin/mqbroker
|
||||
#Win environment
|
||||
. \bin\mqbroker.cmd
|
||||
```
|
||||
|
||||
## Run the demo
|
||||
|
||||
After the preparation work is done, you can run the demo to experience the user order (distributed transaction capability) and simulate the high traffic volume (meltdown limit and peak shaving capability) depending on different usage scenarios.
|
||||
|
||||
The first step is to start the `integrated_frontend` and `integrated_gateway` projects respectively.
|
||||
|
||||
- The gateway module is the gateway to the entire best practice instance.
|
||||
- frontend is the simple front-end page for the best practice.
|
||||
|
||||
### Distributed transaction capability
|
||||
|
||||
#### scenario description
|
||||
|
||||
For the distributed transaction capability, we provide a scenario **where a user places an order for goods** and after placing the order.
|
||||
|
||||
- First request the inventory module and deduct the inventory
|
||||
- Deducts the account balance
|
||||
- Generate order information to return a response
|
||||
|
||||
##### start test
|
||||
|
||||
Start the `integrated_storage`, `integrated_account`, `integrated_order` microservices separately.
|
||||
|
||||
Visit `http://127.0.0.1:8080/order` to experience the corresponding scenario.
|
||||
|
||||
By clicking directly on the order button to submit the form, we simulate the client sending a request to the gateway to create an order.
|
||||
|
||||
- The user's userId is admin
|
||||
- The user places an order for item number 1
|
||||
- The number of items purchased in this order is 1
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914153234414.png)
|
||||
|
||||
In this demo, for demonstration purposes, the unit price of each item is 2.
|
||||
|
||||
In the previous preparation, when **initialising the business database table** we created a new user userId = admin with a balance of $3 and a new item numbered 1 with 100 items in stock.
|
||||
|
||||
So by doing the above, we create an order, deducting the number of units in stock for item number 1 (100-1=99) and deducting the balance of the admin user (3-2=1).
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914153126925.png)
|
||||
|
||||
If the same interface is requested again, again the stock is deducted first (99-1=98), but an exception is thrown because the admin user's balance is insufficient and is caught by Seata, which performs a two-stage commit of the distributed transaction and rolls back the transaction.
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914153313127.png)
|
||||
|
||||
You can see that the database still has 99 records in stock because of the rollback.
|
||||
|
||||
### Melt limit, peak shaving capability
|
||||
|
||||
#### Scenario description
|
||||
|
||||
For service fusion limiting in the context of high traffic and peak and valley reduction, we provide a scenario where **users like an item**. In this scenario, we provide two ways to deal with high traffic.
|
||||
|
||||
- Sentinel binds a specified gateway route on the gateway side for fusion degradation of the service.
|
||||
- RocketMQ performs traffic clipping, where the producer sends messages to RocketMQ during high traffic requests, while the consumer pulls and consumes at a configurable consumption rate, reducing the pressure of high traffic direct requests to the database to increase the number of likes requested.
|
||||
|
||||
#### startup tests
|
||||
|
||||
Start the `integrated_provider` and `integrated_consumer` modules separately.
|
||||
|
||||
- Sentinel service meltdown downgrade
|
||||
|
||||
Visit `http://127.0.0.1:8080/sentinel` to experience the corresponding scenario.
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914155720469.png)
|
||||
|
||||
The Gateway routing point service has a flow limit rule of 5, while 10 concurrent requests are simulated on the front-end through asynchronous processing.
|
||||
|
||||
So you can see that Sentinel is fusing the service on the Gateway side to return a fallback to the client for the extra traffic, while the number of likes in the database is updated (+5).
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914155755103.png)
|
||||
|
||||
- RocketMQ does peak and valley reduction
|
||||
|
||||
Visit `http://127.0.0.1:8080/rocketmq` to experience the corresponding scenario.
|
||||
|
||||
As we have previously configured the consumption rate and interval of the `integrated-consumer` consumer module in Nacos, we simulate 1000 requests for likes at the click of a button, and for 1000 requests for likes, the `integrated_provider`
|
||||
In the consumer module, we consume at the configured consumption rate and update the database with the product data, simulating the RocketMQ peak-shaving feature in heavy traffic.
|
||||
|
||||
You can see that the number of likes in the database is being dynamically updated.
|
||||
|
||||
![](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220914155815191.png)
|
||||
|
||||
## Other
|
||||
|
||||
This example **is just a selection of the typical features of each component to serve the application scenario**.
|
||||
|
||||
Of course, there is more to each component than what is demonstrated in the best practices, so if you are interested or want to go deeper, you are welcome to study the individual example documentation for each component.
|
||||
|
||||
- Nacos Examples
|
||||
- [nacos-config-example](../../nacos-example/nacos-config-example/readme-zh.md)
|
||||
- [nacos-discovery-example](../../nacos-example/nacos-discovery-example/readme-zh.md)
|
||||
- [Sentinel-Core-Example](../../sentinel-example/sentinel-core-example/readme-zh.md)
|
||||
- [Seata Examples](../../seata-example/readme-zh.md)
|
||||
- [RocketMQ Example](../../rocketmq-example/readme-zh.md)
|
@ -0,0 +1,85 @@
|
||||
# Integrated Example
|
||||
|
||||
## Project Description
|
||||
|
||||
This project is a demo of Spring Cloud Alibaba containerized deployment best practices, and is an example project integrating Spring Cloud Alibaba components (Nacos, Sentinel, Seata, RocketMQ).
|
||||
|
||||
The main components used and their usage features are as follows.
|
||||
|
||||
- Spring Cloud Gateway:gateway
|
||||
- Nacos:configuration centre and service registry
|
||||
- Sentinel:fusion flow limiting
|
||||
- Seata:Distributed Transactions
|
||||
- RocketMQ:message queues for peak and valley reduction
|
||||
- Docker:Microservices Containerized Deployment
|
||||
- Kubernetes Helm Chart
|
||||
|
||||
![Overall Overview](https://my-img-1.oss-cn-hangzhou.aliyuncs.com/image-20220816004541921.png)
|
||||
|
||||
## Application Scenario Description
|
||||
|
||||
In this demo, we provide two business scenarios.
|
||||
|
||||
1) A scenario where a user places an order for goods and after placing the order.
|
||||
|
||||
- First request the inventory module to deduct the inventory
|
||||
|
||||
- Deduct the account balance
|
||||
|
||||
- Generate order information and return a response
|
||||
|
||||
2) The user likes the goods (simulating the producer-consumer application scenario of MQ) and returns the details (number of likes, etc.) after the goods have been liked.
|
||||
|
||||
### Detailed description of the component
|
||||
|
||||
1) In which the scenario where the user places an order for the goods mainly uses Seata to perform distributed transactions to represent the capabilities.
|
||||
|
||||
2) The scenario where the user likes a product simulates a high traffic environment with Sentinel for flow limiting or RocketMQ for peak shaving. In this scenario, we provide two ways to deal with high traffic.
|
||||
|
||||
- Sentinel binds a specified gateway route on the gateway side for service fusion degradation.
|
||||
- RocketMQ performs peak-shaving, where producers send messages to RocketMQ and consumers pull and consume at configurable consumption rates, reducing the pressure of high traffic direct requests to the database and increasing the number of likes.
|
||||
|
||||
#### SpringCloud Gateway
|
||||
|
||||
A gateway to the microservices module.
|
||||
|
||||
Spring Cloud GateWay integrates with Nacos, enabling dynamic routing configuration.
|
||||
|
||||
By listening for changes to the Nacos configuration, the service gateway routing configuration is dynamically refreshed so that each time the routing information changes, there is no need to modify the configuration file and then restart the service.
|
||||
|
||||
#### Nacos
|
||||
|
||||
The configuration centre for each microservice, the service registry.
|
||||
|
||||
- Configuration Centre
|
||||
- Shared configuration: MySQL data source related information configuration.
|
||||
|
||||
- Registration Centre
|
||||
- All microservice modules are registered to Nacos for service registration and discovery.
|
||||
- Integration with SpringCloud Gateway gateway.
|
||||
|
||||
#### Seata
|
||||
|
||||
Seata-based AT model for distributed transaction processing for the Inventory, Accounts and Orders modules.
|
||||
|
||||
Roll back transactions whenever stock is low/account balance is low.
|
||||
|
||||
#### Sentinel
|
||||
|
||||
Service fusion flow limiting for point and click scenarios.
|
||||
|
||||
Integrates Nacos Configuration Center with Spring Cloud Gateway to enable dynamic configuration of fused flow limiting rules for specified routing rules.
|
||||
|
||||
#### RocketMQ
|
||||
|
||||
Used for peaks and valleys reduction of like service traffic.
|
||||
|
||||
By sending high volume like requests from the producer to the mq, the consumer module pulls from the mq and consumes them with a certain frequency, rather than simply fusing and limiting the degradation of the service directly, enabling RocketMQ's ability to shave peaks and valleys for high volume traffic.
|
||||
|
||||
## Release Notes
|
||||
|
||||
This project provides a [local-deployment](local-deployment.md) and a [Kubernetes Helm-Chart version](kubernetes-deployment.md).
|
||||
|
||||
- To learn how to configure the components and build the complete environment, we recommend learning the [local-deployment](local-deployment.md).
|
||||
|
||||
- If you want to quickly experience the components on a K8S cluster and skip the process of deploying each component, please check out the [Kubernetes Helm-Chart version](kubernetes-deployment.md).
|
@ -0,0 +1,2 @@
|
||||
# Spring Cloud Alibaba容器化部署最佳实践 | Kubernetes Helm-Chart 版本
|
||||
建设中
|
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-account</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>integrated-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class AccountServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AccountServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account.controller;
|
||||
|
||||
import com.alibaba.cloud.integration.account.dto.AccountDTO;
|
||||
import com.alibaba.cloud.integration.account.service.AccountService;
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/account")
|
||||
public class AccountController {
|
||||
|
||||
@Autowired
|
||||
private AccountService accountService;
|
||||
|
||||
@PostMapping("/reduce-balance")
|
||||
public Result<?> reduceBalance(@RequestBody AccountDTO accountDTO) {
|
||||
try {
|
||||
accountService.reduceBalance(accountDTO.getUserId(), accountDTO.getPrice());
|
||||
}
|
||||
catch (BusinessException e) {
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
return Result.success("");
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public Result<?> getRemainAccount(String userId) {
|
||||
return accountService.getRemainAccount(userId);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account.dto;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class AccountDTO {
|
||||
|
||||
private String userId;
|
||||
|
||||
private Integer price;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Integer price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account.mapper;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface AccountMapper {
|
||||
|
||||
@Select("SELECT money FROM account WHERE user_id = #{userId}")
|
||||
Integer getBalance(@Param("userId") String userId);
|
||||
|
||||
@Update("UPDATE account SET money = money - #{price},update_time = #{updateTime} WHERE user_id = #{userId} AND money >= ${price}")
|
||||
int reduceBalance(@Param("userId") String userId, @Param("price") Integer price,
|
||||
@Param("updateTime") Timestamp updateTime);
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account.service;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface AccountService {
|
||||
|
||||
void reduceBalance(String userId, Integer price) throws BusinessException;
|
||||
|
||||
Result<?> getRemainAccount(String userId);
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.account.service.impl;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.alibaba.cloud.integration.account.mapper.AccountMapper;
|
||||
import com.alibaba.cloud.integration.account.service.AccountService;
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import io.seata.core.context.RootContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Service
|
||||
public class AccountServiceImpl implements AccountService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private AccountMapper accountMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void reduceBalance(String userId, Integer price) throws BusinessException {
|
||||
logger.info("[reduceBalance] currenet XID: {}", RootContext.getXID());
|
||||
|
||||
checkBalance(userId, price);
|
||||
|
||||
Timestamp updateTime = new Timestamp(System.currentTimeMillis());
|
||||
int updateCount = accountMapper.reduceBalance(userId, price, updateTime);
|
||||
if (updateCount == 0) {
|
||||
throw new BusinessException("reduce balance failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<?> getRemainAccount(String userId) {
|
||||
Integer balance = accountMapper.getBalance(userId);
|
||||
if (balance == null) {
|
||||
return Result.failed("wrong userId,please check the userId");
|
||||
}
|
||||
return Result.success(balance);
|
||||
}
|
||||
|
||||
private void checkBalance(String userId, Integer price) throws BusinessException {
|
||||
Integer balance = accountMapper.getBalance(userId);
|
||||
if (balance < price) {
|
||||
throw new BusinessException("no enough balance");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
server:
|
||||
port: 8012
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: integrated-account
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
file-extension: yaml
|
||||
group: integrated-example
|
||||
shared-dataids: datasorce-config.yaml
|
||||
|
||||
seata:
|
||||
application-id: ${spring.application.name}
|
||||
tx-service-group: ${spring.application.name}-group
|
||||
service:
|
||||
vgroup-mapping:
|
||||
integrated-account-group: default
|
||||
grouplist:
|
||||
default: localhost:8091
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-common</artifactId>
|
||||
|
||||
</project>
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.common;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.common;
|
||||
|
||||
public interface IResult {
|
||||
|
||||
/**
|
||||
* Get result code.
|
||||
* @return result code
|
||||
*/
|
||||
Integer getCode();
|
||||
|
||||
/**
|
||||
* Get result message.
|
||||
* @return result message
|
||||
*/
|
||||
String getMessage();
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.common;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class Result<T> {
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
private T data;
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
return new Result<>(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(),
|
||||
data);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(String message, T data) {
|
||||
return new Result<>(ResultEnum.SUCCESS.getCode(), message, data);
|
||||
}
|
||||
|
||||
public static Result<?> failed() {
|
||||
return new Result<>(ResultEnum.COMMON_FAILED.getCode(),
|
||||
ResultEnum.COMMON_FAILED.getMessage(), null);
|
||||
}
|
||||
|
||||
public static Result<?> failed(String message) {
|
||||
return new Result<>(ResultEnum.COMMON_FAILED.getCode(), message, null);
|
||||
}
|
||||
|
||||
public static Result<?> failed(IResult errorResult) {
|
||||
return new Result<>(errorResult.getCode(), errorResult.getMessage(), null);
|
||||
}
|
||||
|
||||
public Result() {
|
||||
}
|
||||
|
||||
public Result(Integer code, String message, T data) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static <T> Result<T> instance(Integer code, String message, T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.common;
|
||||
|
||||
/**
|
||||
* Integrated Example common result enum class.
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public enum ResultEnum implements IResult {
|
||||
|
||||
/**
|
||||
* return success result.
|
||||
*/
|
||||
SUCCESS(2001, "接口调用成功"),
|
||||
/**
|
||||
* return business common failed.
|
||||
*/
|
||||
COMMON_FAILED(2003, "接口调用失败");
|
||||
|
||||
private Integer code;
|
||||
|
||||
private String message;
|
||||
|
||||
ResultEnum() {
|
||||
}
|
||||
|
||||
ResultEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>integrated-frontend</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.frontend;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author HuangSir
|
||||
* @date 2022-09-08 14:11
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class FrontendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FrontendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.frontend.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* @author HuangSir
|
||||
* @date 2022-09-08 14:00
|
||||
*/
|
||||
@Controller
|
||||
public class IntegrationController {
|
||||
|
||||
@RequestMapping("/order")
|
||||
public String order() {
|
||||
return "order";
|
||||
}
|
||||
|
||||
@RequestMapping("/rocketmq")
|
||||
public String rocketmq() {
|
||||
return "rocketmq";
|
||||
}
|
||||
|
||||
@RequestMapping("/sentinel")
|
||||
public String sentinel() {
|
||||
return "sentinel";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title></title>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
||||
</head>
|
||||
<body th:style="${'background-color:' + backgroundColor }">
|
||||
<div style="margin: 30px auto 0 30px;">
|
||||
<div id="orderSection">
|
||||
<label>商品下单场景:</label>
|
||||
<form id="orderForm">
|
||||
<div>
|
||||
<label>用户ID</label>
|
||||
<input type="text" id="userId" name="userId" value="admin"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>商品编号</label>
|
||||
<input type="text" id="commodityCode" name="commodityCode" value="1"/>
|
||||
</div>
|
||||
<div>
|
||||
<label>商品个数</label>
|
||||
<input type="number" name="count" value="1"/>
|
||||
</div>
|
||||
<button type="button" class="btnStart">提交</button>
|
||||
</form>
|
||||
</div>
|
||||
<div id="orderResultSection" style="margin-top: 30px; border-top: 1px solid #eaeaea;">
|
||||
</div>
|
||||
</div>
|
||||
<script charset="utf-8">
|
||||
$(".btnStart").click(function () {
|
||||
$('#orderResultSection').empty();
|
||||
var userId = $("#userId").val();
|
||||
var commodityCode = $("#commodityCode").val();
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/storage/",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "commodityCode=" + commodityCode,
|
||||
async:false,
|
||||
success: function (res) {
|
||||
$('#orderResultSection').append(`<p> 执行分布式业务前商品库存: ${res.data} </p>`);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/account/",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "userId=" + userId,
|
||||
async:false,
|
||||
success: function (res) {
|
||||
$('#orderResultSection').append(`<p> 执行分布式业务前账户余额: ${res.data}</p>`);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "http://localhost:8010/order/create",
|
||||
data: $('#orderForm').serialize(),
|
||||
dataType: 'json',
|
||||
async:false,
|
||||
success: function (res) {
|
||||
$('#orderResultSection').append(`<p> ${res.message} </p>`);
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/storage/",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "commodityCode=" + commodityCode,
|
||||
async:false,
|
||||
success: function (res) {
|
||||
$('#orderResultSection').append(`<p> 执行分布式业务后商品库存: ${res.data}</p>`);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/account/",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "userId=" + userId,
|
||||
async:false,
|
||||
success: function (res) {
|
||||
$('#orderResultSection').append(`<p> 执行分布式业务后账户余额: ${res.data}</p>`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,79 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title></title>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
||||
</head>
|
||||
<body th:style="${'background-color:' + backgroundColor }">
|
||||
<div style="margin: 30px auto 0 30px;">
|
||||
<div id="SentinelSection">
|
||||
<label>Sentinel 限流降级场景:</label>
|
||||
<br>
|
||||
<label>被点赞的商品ID</label>
|
||||
<input id="itemId" style="width: 200px;height: 20px;" value="1">
|
||||
<br>
|
||||
<button class="btnStart">开始调用</button>
|
||||
</div>
|
||||
<div id="sentinelResultSection" style="margin-top: 30px; border-top: 1px solid #eaeaea;">
|
||||
</div>
|
||||
</div>
|
||||
<script charset="utf-8">
|
||||
$('.btnStart').click(() => {
|
||||
$('#sentinelResultSection').empty();
|
||||
var itemId = $('#itemId').val();
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/praise/query",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "itemId=" + itemId,
|
||||
async: false,
|
||||
success: function (res) {
|
||||
$('#sentinelResultSection').append(`<p> 点赞前的点赞数: ${res} </p>`);
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/praise/sentinel",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "itemId=" + itemId,
|
||||
success: function (res) {
|
||||
console.log(res)
|
||||
$('#sentinelResultSection').append(`<p> ${getDateTime()}: ${res}</p>`);
|
||||
},
|
||||
error: function (res) {
|
||||
console.log(res)
|
||||
$('#sentinelResultSection').append(`<p> ${getDateTime()}: 请求失败,接口被限流 </p>`);
|
||||
}
|
||||
});
|
||||
}
|
||||
timeoutid = setTimeout(queryRes, 1000);
|
||||
function queryRes() {
|
||||
$.ajax({
|
||||
url: "http://localhost:8010/praise/query",
|
||||
type: "get",
|
||||
dataType: "json",
|
||||
data: "itemId=" + $('#itemId').val(),
|
||||
success: function (res) {
|
||||
$('#sentinelResultSection').append(`<p> 点赞后的点赞数: ${res} </p>`);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
const getDateTime = () => {
|
||||
const myDate = new Date;
|
||||
const year = myDate.getFullYear(); //获取当前年
|
||||
const month = myDate.getMonth() + 1; //获取当前月
|
||||
const date = myDate.getDate(); //获取当前日
|
||||
const hours = myDate.getHours();
|
||||
const minutes = myDate.getMinutes();
|
||||
const seconds = myDate.getSeconds();
|
||||
return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-gateway</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class GatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GatewayApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.gateway.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.reactive.CorsWebFilter;
|
||||
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Configuration
|
||||
public class GatewayConfig {
|
||||
|
||||
private final List<ViewResolver> viewResolvers;
|
||||
|
||||
private final ServerCodecConfigurer serverCodecConfigurer;
|
||||
|
||||
public GatewayConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider,
|
||||
ServerCodecConfigurer serverCodecConfigurer) {
|
||||
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
|
||||
this.serverCodecConfigurer = serverCodecConfigurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public GlobalFilter sentinelGatewayFilter() {
|
||||
return new SentinelGatewayFilter();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void initGatewayRules() {
|
||||
Set<GatewayFlowRule> rules = new HashSet<>();
|
||||
rules.add(
|
||||
new GatewayFlowRule("praiseItemSentinel").setCount(5).setIntervalSec(1));
|
||||
GatewayRuleManager.loadRules(rules);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
|
||||
// Register the block exception handler for Spring Cloud Gateway.
|
||||
return new SentinelGatewayBlockExceptionHandler(viewResolvers,
|
||||
serverCodecConfigurer);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void initBlockHandlers() {
|
||||
BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
|
||||
@Override
|
||||
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange,
|
||||
Throwable throwable) {
|
||||
return ServerResponse.status(HttpStatus.OK)
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.body(BodyInserters.fromObject("此接口被限流了"));
|
||||
}
|
||||
};
|
||||
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsWebFilter corsFilter() {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.addAllowedOrigin("*");
|
||||
config.setAllowCredentials(true);
|
||||
config.addAllowedHeader("*");
|
||||
config.addAllowedMethod("*");
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
|
||||
return new CorsWebFilter(source);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
server:
|
||||
port: 8010
|
||||
spring:
|
||||
application:
|
||||
name: integrated-gateway
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
file-extension: yaml
|
||||
group: integrated-example
|
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-order</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>integrated-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableFeignClients
|
||||
public class OrderServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OrderServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.controller;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.order.service.OrderService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/order")
|
||||
public class OrderController {
|
||||
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
|
||||
@PostMapping("/create")
|
||||
public Result<?> createOrder(@RequestParam("userId") String userId,
|
||||
@RequestParam("commodityCode") String commodityCode,
|
||||
@RequestParam("count") Integer count) {
|
||||
Result<?> res = null;
|
||||
try {
|
||||
res = orderService.createOrder(userId, commodityCode, count);
|
||||
}
|
||||
catch (BusinessException e) {
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.entity;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class Order {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private String userId;
|
||||
|
||||
private String commodityCode;
|
||||
|
||||
private Integer count;
|
||||
|
||||
private Integer money;
|
||||
|
||||
private Timestamp createTime;
|
||||
|
||||
private Timestamp updateTime;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getCommodityCode() {
|
||||
return commodityCode;
|
||||
}
|
||||
|
||||
public void setCommodityCode(String commodityCode) {
|
||||
this.commodityCode = commodityCode;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Integer getMoney() {
|
||||
return money;
|
||||
}
|
||||
|
||||
public void setMoney(Integer money) {
|
||||
this.money = money;
|
||||
}
|
||||
|
||||
public Timestamp getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Timestamp createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Timestamp getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Timestamp updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Order{" + "id=" + id + ", userId='" + userId + '\'' + ", commodityCode='"
|
||||
+ commodityCode + '\'' + ", count=" + count + ", money=" + money
|
||||
+ ", createTime=" + createTime + ", updateTime=" + updateTime + '}';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.feign;
|
||||
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.order.feign.dto.AccountDTO;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@FeignClient(name = "integrated-account")
|
||||
public interface AccountServiceFeignClient {
|
||||
|
||||
@PostMapping("/account/reduce-balance")
|
||||
Result<?> reduceBalance(@RequestBody AccountDTO accountReduceBalanceDTO);
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.feign;
|
||||
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.order.feign.dto.StorageDTO;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@FeignClient(name = "integrated-storage")
|
||||
public interface StorageServiceFeignClient {
|
||||
|
||||
@PostMapping("/storage/reduce-stock")
|
||||
Result<?> reduceStock(@RequestBody StorageDTO productReduceStockDTO);
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.feign.dto;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class AccountDTO {
|
||||
|
||||
private String userId;
|
||||
|
||||
private Integer price;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Integer price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.feign.dto;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class StorageDTO {
|
||||
|
||||
private String commodityCode;
|
||||
|
||||
private Integer count;
|
||||
|
||||
public String getCommodityCode() {
|
||||
return commodityCode;
|
||||
}
|
||||
|
||||
public void setCommodityCode(String commodityCode) {
|
||||
this.commodityCode = commodityCode;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.mapper;
|
||||
|
||||
import com.alibaba.cloud.integration.order.entity.Order;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Options;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface OrderMapper {
|
||||
|
||||
@Insert("INSERT INTO `order` (user_id, commodity_code,money,create_time,update_time) VALUES (#{userId}, #{commodityCode},#{money},#{createTime},#{updateTime})")
|
||||
@Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
|
||||
int saveOrder(Order order);
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.service;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface OrderService {
|
||||
|
||||
Result<?> createOrder(String userId, String commodityCode, Integer count)
|
||||
throws BusinessException;
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.order.service.impl;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.order.entity.Order;
|
||||
import com.alibaba.cloud.integration.order.feign.AccountServiceFeignClient;
|
||||
import com.alibaba.cloud.integration.order.feign.StorageServiceFeignClient;
|
||||
import com.alibaba.cloud.integration.order.feign.dto.AccountDTO;
|
||||
import com.alibaba.cloud.integration.order.feign.dto.StorageDTO;
|
||||
import com.alibaba.cloud.integration.order.mapper.OrderMapper;
|
||||
import com.alibaba.cloud.integration.order.service.OrderService;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static com.alibaba.cloud.integration.common.ResultEnum.COMMON_FAILED;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private OrderMapper orderMapper;
|
||||
|
||||
@Autowired
|
||||
private AccountServiceFeignClient accountService;
|
||||
|
||||
@Autowired
|
||||
private StorageServiceFeignClient storageService;
|
||||
|
||||
@Override
|
||||
@GlobalTransactional
|
||||
public Result<?> createOrder(String userId, String commodityCode, Integer count) {
|
||||
|
||||
logger.info("[createOrder] current XID: {}", RootContext.getXID());
|
||||
|
||||
// deduct storage
|
||||
StorageDTO storageDTO = new StorageDTO();
|
||||
storageDTO.setCommodityCode(commodityCode);
|
||||
storageDTO.setCount(count);
|
||||
Integer storageCode = storageService.reduceStock(storageDTO).getCode();
|
||||
if (storageCode.equals(COMMON_FAILED.getCode())) {
|
||||
throw new BusinessException("stock not enough");
|
||||
}
|
||||
|
||||
// deduct balance
|
||||
int price = count * 2;
|
||||
AccountDTO accountDTO = new AccountDTO();
|
||||
accountDTO.setUserId(userId);
|
||||
accountDTO.setPrice(price);
|
||||
Integer accountCode = accountService.reduceBalance(accountDTO).getCode();
|
||||
if (accountCode.equals(COMMON_FAILED.getCode())) {
|
||||
throw new BusinessException("balance not enough");
|
||||
}
|
||||
|
||||
// save order
|
||||
Order order = new Order();
|
||||
order.setUserId(userId);
|
||||
order.setCommodityCode(commodityCode);
|
||||
order.setCount(count);
|
||||
order.setMoney(price);
|
||||
order.setCreateTime(new Timestamp(System.currentTimeMillis()));
|
||||
order.setUpdateTime(new Timestamp(System.currentTimeMillis()));
|
||||
orderMapper.saveOrder(order);
|
||||
logger.info("[createOrder] orderId: {}", order.getId());
|
||||
|
||||
return Result.success(order);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
server:
|
||||
port: 8013
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: integrated-order
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
file-extension: yaml
|
||||
group: integrated-example
|
||||
shared-dataids: datasorce-config.yaml
|
||||
|
||||
seata:
|
||||
application-id: ${spring.application.name}
|
||||
tx-service-group: ${spring.application.name}-group
|
||||
service:
|
||||
vgroup-mapping:
|
||||
integrated-order-group: default
|
||||
grouplist:
|
||||
default: localhost:8091
|
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-praise-consumer</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer;
|
||||
|
||||
import com.alibaba.cloud.integration.consumer.message.PraiseSink;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableBinding(PraiseSink.class)
|
||||
public class PraiseConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PraiseConsumerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.controller;
|
||||
|
||||
import com.alibaba.cloud.integration.consumer.service.PraiseService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/praise")
|
||||
public class PraiseController {
|
||||
|
||||
@Autowired
|
||||
private PraiseService praiseService;
|
||||
|
||||
@GetMapping("/query")
|
||||
public Integer getPraise(Integer itemId) {
|
||||
return praiseService.getPraise(itemId);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.listener;
|
||||
|
||||
import com.alibaba.cloud.integration.consumer.message.PraiseMessage;
|
||||
import com.alibaba.cloud.integration.consumer.message.PraiseSink;
|
||||
import com.alibaba.cloud.integration.consumer.service.PraiseService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Component
|
||||
public class PraiseConsumer {
|
||||
|
||||
@Autowired
|
||||
private PraiseService praiseService;
|
||||
|
||||
@StreamListener(PraiseSink.PRAISE_INPUT)
|
||||
public void onMessage(@Payload PraiseMessage message) {
|
||||
praiseService.praiseItem(message.getItemId());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.mapper;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface PraiseMapper {
|
||||
|
||||
@Update("update item set praise = praise+1,update_time=#{updateTime} where id = #{itemId}")
|
||||
int praiseItem(@Param("itemId") Integer itemId,
|
||||
@Param("updateTime") Timestamp updateTime);
|
||||
|
||||
@Select("select praise from item where id = #{itemId}")
|
||||
int getPraise(@Param("itemId") Integer itemId);
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.message;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class PraiseMessage {
|
||||
|
||||
private Integer itemId;
|
||||
|
||||
public Integer getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public void setItemId(Integer itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PraiseMessage{" + "itemId=" + itemId + '}';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.message;
|
||||
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface PraiseSink {
|
||||
|
||||
/**
|
||||
* rocketmq input name.
|
||||
*/
|
||||
String PRAISE_INPUT = "praise-input";
|
||||
|
||||
@Input(PRAISE_INPUT)
|
||||
SubscribableChannel praiseInput();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.service;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface PraiseService {
|
||||
|
||||
void praiseItem(Integer itemId);
|
||||
|
||||
int getPraise(Integer itemId);
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.consumer.service.impl;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.alibaba.cloud.integration.consumer.mapper.PraiseMapper;
|
||||
import com.alibaba.cloud.integration.consumer.service.PraiseService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Service
|
||||
public class PraiseServiceImpl implements PraiseService {
|
||||
|
||||
@Autowired
|
||||
private PraiseMapper praiseMapper;
|
||||
|
||||
@Override
|
||||
public void praiseItem(Integer itemId) {
|
||||
Timestamp updateTime = new Timestamp(System.currentTimeMillis());
|
||||
praiseMapper.praiseItem(itemId, updateTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPraise(Integer itemId) {
|
||||
return praiseMapper.getPraise(itemId);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
spring:
|
||||
application:
|
||||
name: integrated-consumer
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
file-extension: yaml
|
||||
server-addr: localhost:8848
|
||||
shared-configs[0]:
|
||||
dataId: datasorce-config.yaml
|
||||
group: integrated-example
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
server:
|
||||
port: 8014
|
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-praise-provider</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.provider;
|
||||
|
||||
import com.alibaba.cloud.integration.provider.message.PraiseSource;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableBinding(PraiseSource.class)
|
||||
public class PraiseProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PraiseProviderApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.provider.controller;
|
||||
|
||||
import com.alibaba.cloud.integration.provider.message.PraiseMessage;
|
||||
import com.alibaba.cloud.integration.provider.message.PraiseSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/praise")
|
||||
public class PraiseController {
|
||||
|
||||
@Autowired
|
||||
private PraiseSource praiseSource;
|
||||
|
||||
@GetMapping({ "/rocketmq", "/sentinel" })
|
||||
public boolean praise(@RequestParam Integer itemId) {
|
||||
PraiseMessage message = new PraiseMessage();
|
||||
message.setItemId(itemId);
|
||||
Message<PraiseMessage> praiseMessage = MessageBuilder.withPayload(message)
|
||||
.build();
|
||||
return praiseSource.praiseOutput().send(praiseMessage);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.provider.message;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class PraiseMessage {
|
||||
|
||||
private Integer itemId;
|
||||
|
||||
public Integer getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public void setItemId(Integer itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PraiseMessage{" + "itemId=" + itemId + '}';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.provider.message;
|
||||
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface PraiseSource {
|
||||
|
||||
@Output("praise-output")
|
||||
MessageChannel praiseOutput();
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
spring:
|
||||
application:
|
||||
name: integrated-provider
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
file-extension: yaml
|
||||
server-addr: localhost:8848
|
||||
group: integrated-example
|
||||
server:
|
||||
port: 8015
|
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>integrated-storage</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.47</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.1.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>integrated-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class StorageServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(StorageServiceApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage.controller;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.storage.dto.StorageDTO;
|
||||
import com.alibaba.cloud.integration.storage.service.StorageService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/storage")
|
||||
public class StorageController {
|
||||
|
||||
@Autowired
|
||||
private StorageService storageService;
|
||||
|
||||
@PostMapping("/reduce-stock")
|
||||
public Result<?> reduceStock(@RequestBody StorageDTO storageDTO) {
|
||||
try {
|
||||
storageService.reduceStock(storageDTO.getCommodityCode(),
|
||||
storageDTO.getCount());
|
||||
}
|
||||
catch (BusinessException e) {
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
return Result.success("");
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public Result<?> getRemainCount(String commodityCode) {
|
||||
return storageService.getRemainCount(commodityCode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage.dto;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public class StorageDTO {
|
||||
|
||||
private String commodityCode;
|
||||
|
||||
private Integer count;
|
||||
|
||||
public String getCommodityCode() {
|
||||
return commodityCode;
|
||||
}
|
||||
|
||||
public void setCommodityCode(String commodityCode) {
|
||||
this.commodityCode = commodityCode;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage.mapper;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface StorageMapper {
|
||||
|
||||
@Select("SELECT `count` FROM storage WHERE commodity_code = #{commodityCode}")
|
||||
Integer getStock(@Param("commodityCode") String commodityCode);
|
||||
|
||||
@Update("UPDATE storage SET count = count - #{count},update_time=#{updateTime} WHERE commodity_code = #{commodityCode}")
|
||||
int reduceStock(@Param("commodityCode") String commodityCode,
|
||||
@Param("count") Integer count, @Param("updateTime") Timestamp updateTime);
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage.service;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
public interface StorageService {
|
||||
|
||||
void reduceStock(String commodityCode, Integer orderCount) throws BusinessException;
|
||||
|
||||
Result<?> getRemainCount(String commodityCode);
|
||||
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.integration.storage.service.impl;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.alibaba.cloud.integration.common.BusinessException;
|
||||
import com.alibaba.cloud.integration.common.Result;
|
||||
import com.alibaba.cloud.integration.storage.mapper.StorageMapper;
|
||||
import com.alibaba.cloud.integration.storage.service.StorageService;
|
||||
import io.seata.core.context.RootContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author TrevorLink
|
||||
*/
|
||||
@Service
|
||||
public class StorageServiceImpl implements StorageService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private StorageMapper storageMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void reduceStock(String commodityCode, Integer count)
|
||||
throws BusinessException {
|
||||
logger.info("[reduceStock] current XID: {}", RootContext.getXID());
|
||||
|
||||
checkStock(commodityCode, count);
|
||||
|
||||
Timestamp updateTime = new Timestamp(System.currentTimeMillis());
|
||||
int updateCount = storageMapper.reduceStock(commodityCode, count, updateTime);
|
||||
if (updateCount == 0) {
|
||||
throw new BusinessException("deduct stock failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<?> getRemainCount(String commodityCode) {
|
||||
Integer stock = storageMapper.getStock(commodityCode);
|
||||
if (stock == null) {
|
||||
return Result.failed("commodityCode wrong,please check commodity code");
|
||||
}
|
||||
return Result.success(stock);
|
||||
}
|
||||
|
||||
private void checkStock(String commodityCode, Integer count)
|
||||
throws BusinessException {
|
||||
Integer stock = storageMapper.getStock(commodityCode);
|
||||
if (stock < count) {
|
||||
throw new BusinessException("no enough stock");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
server:
|
||||
port: 8011
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: integrated-storage
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
config:
|
||||
server-addr: localhost:8848
|
||||
file-extension: yaml
|
||||
group: integrated-example
|
||||
shared-dataids: datasorce-config.yaml
|
||||
|
||||
seata:
|
||||
application-id: ${spring.application.name}
|
||||
tx-service-group: ${spring.application.name}-group
|
||||
service:
|
||||
vgroup-mapping:
|
||||
integrated-storage-group: default
|
||||
grouplist:
|
||||
default: localhost:8091
|
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
groupId="integrated-example"
|
||||
echo "Nacos auto config started"
|
||||
datasourceConfig=$(cat ../config/datasource-config.yaml)
|
||||
storageConfig=$(cat ../config/integrated-storage.yaml)
|
||||
accountConfig=$(cat ../config/integrated-account.yaml)
|
||||
orderConfig=$(cat ../config/integrated-order.yaml)
|
||||
gatewayConfig=$(cat ../config/integrated-gateway.yaml)
|
||||
providerConfig=$(cat ../config/integrated-provider.yaml)
|
||||
consumerConfig=$(cat ../config/integrated-consumer.yaml)
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=datasource-config.yaml&group=${groupId}&content=${datasourceConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-storage.yaml&group=${groupId}&content=${storageConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-account.yaml&group=${groupId}&content=${accountConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-order.yaml&group=${groupId}&content=${orderConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-gateway.yaml&group=${groupId}&content=${gatewayConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-provider.yaml&group=${groupId}&content=${providerConfig}"
|
||||
curl -X POST "127.0.0.1:8848/nacos/v1/cs/configs" -d "dataId=integrated-consumer.yaml&group=${groupId}&content=${consumerConfig}"
|
||||
echo "Nacos config pushed successfully finished"
|
@ -0,0 +1,121 @@
|
||||
-- Storage库存微服务的数据库业务初始化
|
||||
DROP DATABASE IF EXISTS integrated_storage;
|
||||
CREATE DATABASE integrated_storage;
|
||||
USE integrated_storage;
|
||||
CREATE TABLE `storage`
|
||||
(
|
||||
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`commodity_code` varchar(255) DEFAULT NULL,
|
||||
`count` int(11) DEFAULT '0',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `commodity_code` (`commodity_code`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 2
|
||||
DEFAULT CHARSET = utf8;
|
||||
INSERT INTO `storage`
|
||||
VALUES ('1', '1', '100', '2022-08-07 22:48:29', '2022-08-14 13:49:05');
|
||||
|
||||
-- Account账户微服务的数据库业务初始化
|
||||
DROP DATABASE IF EXISTS integrated_account;
|
||||
CREATE DATABASE integrated_account;
|
||||
USE integrated_account;
|
||||
CREATE TABLE `account`
|
||||
(
|
||||
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` varchar(255) DEFAULT NULL,
|
||||
`money` int(11) DEFAULT '0',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 2
|
||||
DEFAULT CHARSET = utf8;
|
||||
INSERT INTO `account`
|
||||
VALUES ('1', 'admin', '3', '2022-08-07 22:53:01', '2022-08-14 13:49:05');
|
||||
|
||||
-- Order订单微服务的数据库业务初始化
|
||||
DROP DATABASE IF EXISTS integrated_order;
|
||||
CREATE DATABASE integrated_order;
|
||||
USE integrated_order;
|
||||
CREATE TABLE `order`
|
||||
(
|
||||
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` varchar(255) DEFAULT NULL,
|
||||
`commodity_code` varchar(255) DEFAULT NULL,
|
||||
`count` int(11) DEFAULT NULL,
|
||||
`money` int(11) DEFAULT '0',
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 16
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- 点赞业务的数据库初始化
|
||||
DROP DATABASE IF EXISTS integrated_praise;
|
||||
CREATE DATABASE integrated_praise;
|
||||
USE integrated_praise;
|
||||
CREATE TABLE `item`
|
||||
(
|
||||
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`praise` int(11) DEFAULT NULL,
|
||||
`create_time` datetime DEFAULT NULL,
|
||||
`update_time` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 2
|
||||
DEFAULT CHARSET = utf8;
|
||||
INSERT INTO `item`
|
||||
VALUES ('1', '0', '2022-08-14 00:33:50', '2022-08-14 14:07:34');
|
||||
-- Storage库存微服务的数据库Seata初始化
|
||||
USE integrated_storage;
|
||||
CREATE TABLE `undo_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`branch_id` bigint(20) NOT NULL,
|
||||
`xid` varchar(100) NOT NULL,
|
||||
`context` varchar(128) NOT NULL,
|
||||
`rollback_info` longblob NOT NULL,
|
||||
`log_status` int(11) NOT NULL,
|
||||
`log_created` datetime NOT NULL,
|
||||
`log_modified` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- Storage库存微服务的数据库Seata初始化
|
||||
USE integrated_account;
|
||||
CREATE TABLE `undo_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`branch_id` bigint(20) NOT NULL,
|
||||
`xid` varchar(100) NOT NULL,
|
||||
`context` varchar(128) NOT NULL,
|
||||
`rollback_info` longblob NOT NULL,
|
||||
`log_status` int(11) NOT NULL,
|
||||
`log_created` datetime NOT NULL,
|
||||
`log_modified` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
||||
|
||||
-- Storage库存微服务的数据库Seata初始化
|
||||
USE integrated_order;
|
||||
CREATE TABLE `undo_log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`branch_id` bigint(20) NOT NULL,
|
||||
`xid` varchar(100) NOT NULL,
|
||||
`context` varchar(128) NOT NULL,
|
||||
`rollback_info` longblob NOT NULL,
|
||||
`log_status` int(11) NOT NULL,
|
||||
`log_created` datetime NOT NULL,
|
||||
`log_modified` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8;
|
Loading…
Reference in New Issue