消息中心完善,升级 spring cloud

This commit is contained in:
wangiegie@gmail.com 2018-01-16 23:22:18 +08:00
parent acd67bc2b2
commit 297af877bd
18 changed files with 301 additions and 148 deletions

View File

@ -90,29 +90,8 @@
<artifactId>fastdfs-spring-boot-starter</artifactId> <artifactId>fastdfs-spring-boot-starter</artifactId>
<version>0.2.0</version> <version>0.2.0</version>
</dependency> </dependency>
<!--阿里大于-->
<dependency>
<groupId>com.aliyun.taobao</groupId>
<artifactId>alidayu-sms</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </dependencies>
<repositories>
<repository>
<id>nexus</id>
<name>nexus Repository</name>
<url>http://218.70.11.118:8081/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<build> <build>
<plugins> <plugins>
</plugins> </plugins>

View File

@ -57,4 +57,9 @@ public interface CommonConstant {
* JSON 资源 * JSON 资源
*/ */
String CONTENT_TYPE = "application/json; charset=utf-8"; String CONTENT_TYPE = "application/json; charset=utf-8";
/**
* 阿里大鱼
*/
String ALIYUN_SMS = "aliyun_sms";
} }

View File

@ -0,0 +1,39 @@
package com.github.pig.common.constant.enums;
/**
* @author lengleng
* @date 2018/1/16
* 短信通道枚举
*/
public enum EnumSmsChannel {
ALIYUN("ALIYUN_SMS", "阿里大鱼");
/**
* 通道名称
*/
private String name;
/**
* 通道描述
*/
private String description;
EnumSmsChannel(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -1,5 +1,7 @@
package com.github.pig.common.util.template; package com.github.pig.common.util.template;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
/** /**
@ -7,7 +9,8 @@ import java.io.Serializable;
* @date 2018/1/15 * @date 2018/1/15
* 短信消息模板 * 短信消息模板
*/ */
public class MobileMsgTemplate implements Serializable{ @Data
public class MobileMsgTemplate implements Serializable {
/** /**
* 手机号 * 手机号
*/ */
@ -16,25 +19,14 @@ public class MobileMsgTemplate implements Serializable{
* 文本 * 文本
*/ */
private String text; private String text;
/**
* 类型通道
*/
private String type;
public MobileMsgTemplate(String mobile, String text) { public MobileMsgTemplate(String mobile, String text, String type) {
this.mobile = mobile; this.mobile = mobile;
this.text = text; this.text = text;
} this.type = type;
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
} }
} }

View File

@ -28,6 +28,14 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId> <artifactId>spring-boot-starter-amqp</artifactId>
</dependency> </dependency>
<!--阿里大于-->
<dependency>
<groupId>com.aliyun.taobao</groupId>
<artifactId>alidayu-sms</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/alidayu-sms-1.0.jar</systemPath>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -0,0 +1,35 @@
package com.github.pig.mc.config;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author lengleng
* @date 2018/1/16
* 阿里大鱼短息服务配置
*/
@Data
@Configuration
@ConditionalOnExpression("!'${sms.aliyun}'.isEmpty()")
@ConfigurationProperties(prefix = "sms.aliyun")
public class SmsAliyunPropertiesConfig {
/**
* 应用ID
*/
private String accessKey;
/**
* 应用秘钥
*/
private String secretKey;
/**
* 短信模板配置
*/
private Map<String, String> channels;
}

View File

@ -0,0 +1,49 @@
package com.github.pig.mc.handler;
import com.github.pig.common.util.template.MobileMsgTemplate;
/**
* @author lengleng
* @date 2018/1/16
* 抽象hander
*/
public abstract class AbstractMessageHandler implements SmsMessageHandler {
/**
* 执行入口
*
* @param mobileMsgTemplate 信息
*/
@Override
public void execute(MobileMsgTemplate mobileMsgTemplate) {
check(mobileMsgTemplate);
if (!process(mobileMsgTemplate)) {
fail(mobileMsgTemplate);
}
}
/**
* 数据校验
*
* @param mobileMsgTemplate 信息
*/
@Override
public abstract void check(MobileMsgTemplate mobileMsgTemplate);
/**
* 业务处理
*
* @param mobileMsgTemplate 信息
* @return boolean
*/
@Override
public abstract boolean process(MobileMsgTemplate mobileMsgTemplate);
/**
* 失败处理
*
* @param mobileMsgTemplate 信息
*/
@Override
public abstract void fail(MobileMsgTemplate mobileMsgTemplate);
}

View File

@ -1,73 +1,82 @@
package com.github.pig.common.util.sms; package com.github.pig.mc.handler;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.Assert;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.mc.config.SmsAliyunPropertiesConfig;
import com.github.pig.mc.utils.constant.SmsChannelTemplateConstant;
import com.github.pig.mc.utils.sms.EnumSmsChannelTemplate;
import com.taobao.api.DefaultTaobaoClient; import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient; import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest; import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse; import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/** /**
* 阿里大于短信发送工具类
*
* @author 浅梦 * @author 浅梦
* @date 2018年1月16日 * @date 2018/1/16
* 阿里大鱼短息服务处理
*/ */
@Slf4j @Slf4j
public class AliDaYuSendUtils { @Component(CommonConstant.ALIYUN_SMS)
//正式环境 public class SmsAliyunMessageHandler extends AbstractMessageHandler {
@Autowired
private SmsAliyunPropertiesConfig smsAliyunPropertiesConfig;
private static final String URL = "http://gw.api.taobao.com/router/rest"; private static final String URL = "http://gw.api.taobao.com/router/rest";
private static final String KEY = "";
private static final String SECRET = "";
public static final String CHANNEL = "";
/**
* 短信签名
*/
public static final String SIGN_NAME_LOGIN = "登录验证";
/** /**
* 发送短信验证码 * 数据校验
* @param channel *
* @param sign_name * @param mobileMsgTemplate 消息
* @param phone
* @param code
* @return
*/ */
public static boolean sendSmsCode(String channel, String sign_name, String phone, String code){ @Override
public void check(MobileMsgTemplate mobileMsgTemplate) {
Assert.isBlank(mobileMsgTemplate.getMobile(), "手机号不能为空");
Assert.isBlank(mobileMsgTemplate.getText(), "验证码不能为空");
}
/**
* 业务处理
*
* @param mobileMsgTemplate 消息
*/
@Override
public boolean process(MobileMsgTemplate mobileMsgTemplate) {
// 配置连接参数URLKEYSECRET // 配置连接参数URLKEYSECRET
TaobaoClient taobaoClient = new DefaultTaobaoClient(URL, KEY, SECRET); TaobaoClient taobaoClient = new DefaultTaobaoClient(URL, smsAliyunPropertiesConfig.getAccessKey(), smsAliyunPropertiesConfig.getSecretKey());
// 配置请求参数 // 配置请求参数
AlibabaAliqinFcSmsNumSendRequest request = new AlibabaAliqinFcSmsNumSendRequest(); AlibabaAliqinFcSmsNumSendRequest request = new AlibabaAliqinFcSmsNumSendRequest();
/** /**
* 公共回传参数消息返回中会透传回该参数举例用户可以传入自己下级的会员ID在消息返回时该会员ID会包含在内用户可以根据该会员ID识别是哪位会员使用了你的应用 * 公共回传参数消息返回中会透传回该参数举例用户可以传入自己下级的会员ID在消息返回时该会员ID会包含在内用户可以根据该会员ID识别是哪位会员使用了你的应用
*/ */
request.setExtend(phone); request.setExtend(mobileMsgTemplate.getMobile());
/** /**
* 短信接收号码支持单个或多个手机号码传入号码为11位手机号码不能入加0或+86群发短信需传多个号码以英文逗号分隔一次调用最多传入200个号码示例18600000000,13911111111,13322222222 * 短信接收号码支持单个或多个手机号码传入号码为11位手机号码不能入加0或+86群发短信需传多个号码以英文逗号分隔一次调用最多传入200个号码示例18600000000,13911111111,13322222222
*/ */
request.setRecNum(phone); request.setRecNum(mobileMsgTemplate.getMobile());
/** /**
* 短信签名传入的短信签名必须是在阿里大鱼管理中心-短信签名管理中的可用签名阿里大鱼已在短信签名管理中通过审核则可传入阿里大鱼传参时去掉引号作为短信签名短信效果示例阿里大鱼欢迎使用阿里大鱼服务 * 短信签名传入的短信签名必须是在阿里大鱼管理中心-短信签名管理中的可用签名阿里大鱼已在短信签名管理中通过审核则可传入阿里大鱼传参时去掉引号作为短信签名短信效果示例阿里大鱼欢迎使用阿里大鱼服务
*/ */
request.setSmsFreeSignName(sign_name); request.setSmsFreeSignName(EnumSmsChannelTemplate.LOGIN_NAME_LOGIN.getDescription());
/** /**
* 短信模板变量传参规则{"key":"value"}key的名字须和申请模板中的变量名一致多个变量之间以逗号隔开示例针对模板验证码${code}您正在进行${product}身份验证打死不要告诉别人哦传参时需传入{"code":"1234","product":"alidayu"} * 短信模板变量传参规则{"key":"value"}key的名字须和申请模板中的变量名一致多个变量之间以逗号隔开示例针对模板验证码${code}您正在进行${product}身份验证打死不要告诉别人哦传参时需传入{"code":"1234","product":"alidayu"}
*/ */
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("product","pig_cloud"); jsonObject.put("product","pig_cloud");
jsonObject.put("code",code); jsonObject.put("code",mobileMsgTemplate.getText());
request.setSmsParamString(jsonObject.toString()); request.setSmsParamString(jsonObject.toString());
/** /**
* 短信模板ID传入的模板必须是在阿里大鱼管理中心-短信模板管理中的可用模板示例SMS_585014 * 短信模板ID传入的模板必须是在阿里大鱼管理中心-短信模板管理中的可用模板示例SMS_585014
*/ */
request.setSmsTemplateCode(channel); request.setSmsTemplateCode(smsAliyunPropertiesConfig.getChannels().get(SmsChannelTemplateConstant.LOGIN_NAME_LOGIN));
/** /**
* 短信类型传入值请填写normal * 短信类型传入值请填写normal
*/ */
request.setSmsType("normal"); request.setSmsType("normal");
try { try {
// 请求接口并获取返回值
AlibabaAliqinFcSmsNumSendResponse response = taobaoClient.execute(request); AlibabaAliqinFcSmsNumSendResponse response = taobaoClient.execute(request);
return response.getResult().getSuccess(); return response.getResult().getSuccess();
}catch (Exception e){ }catch (Exception e){
@ -75,12 +84,13 @@ public class AliDaYuSendUtils {
} }
} }
/** /**
* 测试一哈 * 失败处理
* @param args *
* @param mobileMsgTemplate 消息
*/ */
public static void main(String[] args) { @Override
log.info("发送结果:" + sendSmsCode(CHANNEL, SIGN_NAME_LOGIN, "1008611", String.valueOf((int)(Math.random()*9+1)*1000))); public void fail(MobileMsgTemplate mobileMsgTemplate) {
log.error("短信发送失败 -> 网关:{} -> 手机号:{}", mobileMsgTemplate.getType(), mobileMsgTemplate.getMobile());
} }
} }

View File

@ -0,0 +1,38 @@
package com.github.pig.mc.handler;
import com.github.pig.common.util.template.MobileMsgTemplate;
/**
* @author lengleng
* @date 2018/1/16
*/
public interface SmsMessageHandler {
/**
* 执行入口
*
* @param mobileMsgTemplate 信息
*/
void execute(MobileMsgTemplate mobileMsgTemplate);
/**
* 数据校验
*
* @param mobileMsgTemplate 信息
*/
void check(MobileMsgTemplate mobileMsgTemplate);
/**
* 业务处理
*
* @param mobileMsgTemplate 信息
* @return boolean
*/
boolean process(MobileMsgTemplate mobileMsgTemplate);
/**
* 失败处理
*
* @param mobileMsgTemplate 信息
*/
void fail(MobileMsgTemplate mobileMsgTemplate);
}

View File

@ -1,13 +1,16 @@
package com.github.pig.mc.listener; package com.github.pig.mc.listener;
import com.github.pig.common.constant.MqQueueConstant; import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.util.sms.AliDaYuSendUtils;
import com.github.pig.common.util.template.MobileMsgTemplate; import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.mc.handler.SmsMessageHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map;
/** /**
* @author lengleng * @author lengleng
* @date 2018年01月15日13:51:53 * @date 2018年01月15日13:51:53
@ -17,14 +20,17 @@ import org.springframework.stereotype.Component;
@Component @Component
@RabbitListener(queues = MqQueueConstant.MOBILE_CODE_QUEUE) @RabbitListener(queues = MqQueueConstant.MOBILE_CODE_QUEUE)
public class MobileCodeReceiveListener { public class MobileCodeReceiveListener {
@Autowired
private Map<String, SmsMessageHandler> messageHandlerMap;
@RabbitHandler @RabbitHandler
public void receive(MobileMsgTemplate mobileMsgTemplate) { public void receive(MobileMsgTemplate mobileMsgTemplate) {
long startTime = System.currentTimeMillis();
boolean status = AliDaYuSendUtils.sendSmsCode( log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getText());
AliDaYuSendUtils.CHANNEL, String type = mobileMsgTemplate.getType();
AliDaYuSendUtils.SIGN_NAME_LOGIN, SmsMessageHandler messageHandler = messageHandlerMap.get(type);
mobileMsgTemplate.getMobile(), messageHandler.execute(mobileMsgTemplate);
mobileMsgTemplate.getText()); long useTime = System.currentTimeMillis() - startTime;
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} -> 发送状态:{}", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getText(), status); log.info("调用 {} 短信网关处理完毕,耗时 {}毫秒", type, useTime);
} }
} }

View File

@ -0,0 +1,13 @@
package com.github.pig.mc.utils.constant;
/**
* @author lengleng
* @date 2018/1/16
* 短信通道模板常量
*/
public interface SmsChannelTemplateConstant {
/**
* 登录验证码
*/
String LOGIN_NAME_LOGIN = "loginCodeChannel";
}

View File

@ -0,0 +1,39 @@
package com.github.pig.mc.utils.sms;
/**
* @author lengleng
* @date 2018/1/16
* 短信通道模板
*/
public enum EnumSmsChannelTemplate {
LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证");
/**
* 模板名称
*/
private String name;
/**
* 模板签名
*/
private String description;
EnumSmsChannelTemplate(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -11,6 +11,7 @@ import com.github.pig.admin.mapper.SysUserMapper;
import com.github.pig.admin.service.SysMenuService; import com.github.pig.admin.service.SysMenuService;
import com.github.pig.admin.service.SysUserRoleService; import com.github.pig.admin.service.SysUserRoleService;
import com.github.pig.admin.service.UserService; import com.github.pig.admin.service.UserService;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant; import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.constant.SecurityConstants; import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.Query; import com.github.pig.common.util.Query;
@ -129,7 +130,7 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
if (tempCode == null) { if (tempCode == null) {
String code = RandomUtil.randomNumbers(4); String code = RandomUtil.randomNumbers(4);
logger.info("短信发送请求消息中心 -> 手机号:{} -> 验证码:{}", mobile, code); logger.info("短信发送请求消息中心 -> 手机号:{} -> 验证码:{}", mobile, code);
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE,new MobileMsgTemplate(mobile,code)); rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE,new MobileMsgTemplate(mobile,code, CommonConstant.ALIYUN_SMS));
redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS); redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS);
result = true; result = true;
} }

View File

@ -19,6 +19,8 @@ public class PigAdminApplicationTest {
System.out.println(stringEncryptor.encrypt("lengleng")); System.out.println(stringEncryptor.encrypt("lengleng"));
System.out.println(stringEncryptor.encrypt("root")); System.out.println(stringEncryptor.encrypt("root"));
System.out.println(stringEncryptor.encrypt("g0HJr2Ltrs0k6tJDY6pDI2aVMUCPSWZDTROLcFMs")); System.out.println(stringEncryptor.encrypt("g0HJr2Ltrs0k6tJDY6pDI2aVMUCPSWZDTROLcFMs"));
System.out.println(stringEncryptor.encrypt("24760324"));
System.out.println(stringEncryptor.encrypt("175d516debb916d3842d981dd3b76061"));
} }
} }

View File

@ -1,62 +0,0 @@
package com.github.pig.admin.controller;
import com.github.pig.admin.dto.UserDto;
import com.xiaoleilu.hutool.http.HttpUtil;
import com.xiaoleilu.hutool.json.JSONUtil;
import org.apache.commons.collections.MapUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* @author lengleng
* @date 2017/12/25
* UserController单元测试
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testUserGet() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}", 1)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.username").value("admin"));
}
@Test
public void testUserAdd() throws Exception {
UserDto userDto = new UserDto();
userDto.setRole(1);
userDto.setNewpassword1("@1312312");
mockMvc.perform(MockMvcRequestBuilders.post("/user")
.contentType(MediaType.APPLICATION_JSON)
.content(JSONUtil.toJsonStr(userDto)))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void testPostEdu() throws Exception {
System.out.println(HttpUtil.post("http://eco.ahau.edu.cn/jc/dtrans", MapUtils.EMPTY_MAP));
}
}

View File

@ -27,12 +27,12 @@
<dependency> <dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId> <artifactId>spring-boot-admin-server</artifactId>
<version>1.5.5</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId> <artifactId>spring-boot-admin-server-ui</artifactId>
<version>1.5.5</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
@ -41,7 +41,7 @@
<dependency> <dependency>
<groupId>de.codecentric</groupId> <groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui-turbine</artifactId> <artifactId>spring-boot-admin-server-ui-turbine</artifactId>
<version>1.5.5</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>

View File

@ -39,7 +39,6 @@
<dependency> <dependency>
<groupId>io.zipkin.java</groupId> <groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId> <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
<version>1.28.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -16,7 +16,7 @@
<pig.version>1.0-ALPHA</pig.version> <pig.version>1.0-ALPHA</pig.version>
<spring-boot.version>1.5.9.RELEASE</spring-boot.version> <spring-boot.version>1.5.9.RELEASE</spring-boot.version>
<spring-cloud.version>Dalston.SR4</spring-cloud.version> <spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
<!--Lombok--> <!--Lombok-->
<lombok.version>[1.0.0,9.99.99]</lombok.version> <lombok.version>[1.0.0,9.99.99]</lombok.version>