ci: 三个模块基础框架搭建

This commit is contained in:
2024-04-01 13:43:44 +08:00
parent 117e379d6b
commit bbe2fd35e1
285 changed files with 1530 additions and 43436 deletions
+60 -1
View File
@@ -1,4 +1,63 @@
/target/
/.idea/
jeecg-boot-module-demo
rebel.xml
#java
*.class
#package file
*.war
*.ear
*.zip
*.tar.gz
*.rar
#maven ignore
target/
build/
#eclipse ignore
.settings/
.project
.classpatch
#Intellij idea
.idea/
/idea/
out/
logs/
*.ipr
*.iml
rebel.xml
*.iws
# temp file
*.log
*.cache
*.diff
*.patch
*.tmp
.DS_Store
node_modules
/node_modules/
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+23
View File
@@ -0,0 +1,23 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.jero.boot</groupId>
<artifactId>jero-boot</artifactId>
<version>2.5.0</version>
</parent>
<artifactId>jero-boot-modules</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>jero-system-local-api</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,176 @@
package com.jero.modules.controller.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jero.common.api.vo.Results;
import com.jero.modules.entity.KhDevice;
import com.jero.modules.service.IKhDeviceService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.system.base.controller.JeroController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.jero.common.aspect.annotation.AutoLog;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
/**
* @Description: 设备
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Api(tags="设备")
@RestController
@RequestMapping("/1/khDevice")
@Slf4j
public class KhDeviceController extends JeroController<KhDevice, IKhDeviceService> {
@Autowired
private IKhDeviceService khDeviceService;
/**
* 分页列表查询
*
* @param khDevice
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "设备-分页列表查询")
@ApiOperation(value="设备-分页列表查询", notes="设备-分页列表查询")
@GetMapping(value = "/page")
public Results<IPage<KhDevice>> queryPageList(KhDevice khDevice,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
IPage<KhDevice> pageList = khDeviceService.queryPage(khDevice, pageNo, pageSize, req);
return Results.OK(pageList);
}
/**
* 列表查询
*
* @param khDevice
* @param req
* @return
*/
@AutoLog(value = "设备-列表查询")
@ApiOperation(value="设备-列表查询", notes="设备-列表查询")
@GetMapping(value = "/list")
public Results<List<KhDevice>> queryList(KhDevice khDevice, HttpServletRequest req) {
List<KhDevice> list = khDeviceService.queryList(khDevice, req);
return Results.OK(list);
}
/**
* 添加
*
* @param khDevice
* @return
*/
@AutoLog(value = "设备-添加")
@ApiOperation(value="设备-添加", notes="设备-添加")
@PostMapping(value = "/add")
public Results<T> add(@Validated @RequestBody KhDevice khDevice) {
khDeviceService.add(khDevice);
return Results.OK("操作成功!");
}
/**
* 编辑
*
* @param khDevice
* @return
*/
@AutoLog(value = "设备-编辑")
@ApiOperation(value="设备-编辑", notes="设备-编辑")
@PostMapping(value = "/edit")
public Results<T> edit(@Validated @RequestBody KhDevice khDevice) {
khDeviceService.editById(khDevice);
return Results.OK("操作成功!");
}
/**
* 通过id删除
*
* @param map
* @return
*/
@AutoLog(value = "设备-通过id删除")
@ApiOperation(value="设备-通过id删除", notes="设备-通过id删除")
@PostMapping(value = "/delete")
public Results<T> delete(@RequestBody Map<String, String> map) {
if(!map.containsKey("id") || StringUtils.isEmpty(map.get("id"))){
return Results.error("请选择数据!");
}
khDeviceService.deleteById(map.get("id"));
return Results.OK("删除成功!");
}
/**
* 批量删除
*
* @param map
* @return
*/
@AutoLog(value = "设备-批量删除")
@ApiOperation(value="设备-批量删除", notes="设备-批量删除")
@PostMapping(value = "/deleteBatch")
public Results<T> deleteBatch(@RequestBody Map<String, String> map) {
if(!map.containsKey("ids") || StringUtils.isEmpty(map.get("ids"))){
return Results.error("请选择数据!");
}
this.khDeviceService.deleteByIds(Arrays.asList(map.get("ids").split(",")));
return Results.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "设备-通过id查询")
@ApiOperation(value="设备-通过id查询", notes="设备-通过id查询")
@GetMapping(value = "/queryById")
public Results<KhDevice> queryById(@RequestParam(name="id",required=true) String id) {
KhDevice khDevice = khDeviceService.queryById(id);
if(khDevice==null) {
return Results.error("未找到对应数据");
}
return Results.OK(khDevice);
}
/**
* 导出excel
*
* @param request
* @param khDevice
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, KhDevice khDevice) {
return super.exportXls(request, khDevice, KhDevice.class, "设备");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Results<KhDevice> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, KhDevice.class);
}
}
@@ -0,0 +1,176 @@
package com.jero.modules.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jero.common.api.vo.Results;
import com.jero.modules.entity.KhSystemSetting;
import com.jero.modules.service.IKhSystemSettingService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.system.base.controller.JeroController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.jero.common.aspect.annotation.AutoLog;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
/**
* @Description: 系统设置
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Api(tags="系统设置")
@RestController
@RequestMapping("/com.jero.modules/khSystemSetting")
@Slf4j
public class KhSystemSettingController extends JeroController<KhSystemSetting, IKhSystemSettingService> {
@Autowired
private IKhSystemSettingService khSystemSettingService;
/**
* 分页列表查询
*
* @param khSystemSetting
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "系统设置-分页列表查询")
@ApiOperation(value="系统设置-分页列表查询", notes="系统设置-分页列表查询")
@GetMapping(value = "/page")
public Results<IPage<KhSystemSetting>> queryPageList(KhSystemSetting khSystemSetting,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
IPage<KhSystemSetting> pageList = khSystemSettingService.queryPage(khSystemSetting, pageNo, pageSize, req);
return Results.OK(pageList);
}
/**
* 列表查询
*
* @param khSystemSetting
* @param req
* @return
*/
@AutoLog(value = "系统设置-列表查询")
@ApiOperation(value="系统设置-列表查询", notes="系统设置-列表查询")
@GetMapping(value = "/list")
public Results<List<KhSystemSetting>> queryList(KhSystemSetting khSystemSetting, HttpServletRequest req) {
List<KhSystemSetting> list = khSystemSettingService.queryList(khSystemSetting, req);
return Results.OK(list);
}
/**
* 添加
*
* @param khSystemSetting
* @return
*/
@AutoLog(value = "系统设置-添加")
@ApiOperation(value="系统设置-添加", notes="系统设置-添加")
@PostMapping(value = "/add")
public Results<T> add(@Validated @RequestBody KhSystemSetting khSystemSetting) {
khSystemSettingService.add(khSystemSetting);
return Results.OK("操作成功!");
}
/**
* 编辑
*
* @param khSystemSetting
* @return
*/
@AutoLog(value = "系统设置-编辑")
@ApiOperation(value="系统设置-编辑", notes="系统设置-编辑")
@PostMapping(value = "/edit")
public Results<T> edit(@Validated @RequestBody KhSystemSetting khSystemSetting) {
khSystemSettingService.editById(khSystemSetting);
return Results.OK("操作成功!");
}
/**
* 通过id删除
*
* @param map
* @return
*/
@AutoLog(value = "系统设置-通过id删除")
@ApiOperation(value="系统设置-通过id删除", notes="系统设置-通过id删除")
@PostMapping(value = "/delete")
public Results<T> delete(@RequestBody Map<String, String> map) {
if(!map.containsKey("id") || StringUtils.isEmpty(map.get("id"))){
return Results.error("请选择数据!");
}
khSystemSettingService.deleteById(map.get("id"));
return Results.OK("删除成功!");
}
/**
* 批量删除
*
* @param map
* @return
*/
@AutoLog(value = "系统设置-批量删除")
@ApiOperation(value="系统设置-批量删除", notes="系统设置-批量删除")
@PostMapping(value = "/deleteBatch")
public Results<T> deleteBatch(@RequestBody Map<String, String> map) {
if(!map.containsKey("ids") || StringUtils.isEmpty(map.get("ids"))){
return Results.error("请选择数据!");
}
this.khSystemSettingService.deleteByIds(Arrays.asList(map.get("ids").split(",")));
return Results.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "系统设置-通过id查询")
@ApiOperation(value="系统设置-通过id查询", notes="系统设置-通过id查询")
@GetMapping(value = "/queryById")
public Results<KhSystemSetting> queryById(@RequestParam(name="id",required=true) String id) {
KhSystemSetting khSystemSetting = khSystemSettingService.queryById(id);
if(khSystemSetting==null) {
return Results.error("未找到对应数据");
}
return Results.OK(khSystemSetting);
}
/**
* 导出excel
*
* @param request
* @param khSystemSetting
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, KhSystemSetting khSystemSetting) {
return super.exportXls(request, khSystemSetting, KhSystemSetting.class, "系统设置");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Results<KhSystemSetting> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, KhSystemSetting.class);
}
}
@@ -0,0 +1,176 @@
package com.jero.modules.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jero.common.api.vo.Results;
import com.jero.modules.entity.KhWellhead;
import com.jero.modules.service.IKhWellheadService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.system.base.controller.JeroController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.jero.common.aspect.annotation.AutoLog;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
/**
* @Description: 井口
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Api(tags="井口")
@RestController
@RequestMapping("/1/khWellhead")
@Slf4j
public class KhWellheadController extends JeroController<KhWellhead, IKhWellheadService> {
@Autowired
private IKhWellheadService khWellheadService;
/**
* 分页列表查询
*
* @param khWellhead
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "井口-分页列表查询")
@ApiOperation(value="井口-分页列表查询", notes="井口-分页列表查询")
@GetMapping(value = "/page")
public Results<IPage<KhWellhead>> queryPageList(KhWellhead khWellhead,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
IPage<KhWellhead> pageList = khWellheadService.queryPage(khWellhead, pageNo, pageSize, req);
return Results.OK(pageList);
}
/**
* 列表查询
*
* @param khWellhead
* @param req
* @return
*/
@AutoLog(value = "井口-列表查询")
@ApiOperation(value="井口-列表查询", notes="井口-列表查询")
@GetMapping(value = "/list")
public Results<List<KhWellhead>> queryList(KhWellhead khWellhead, HttpServletRequest req) {
List<KhWellhead> list = khWellheadService.queryList(khWellhead, req);
return Results.OK(list);
}
/**
* 添加
*
* @param khWellhead
* @return
*/
@AutoLog(value = "井口-添加")
@ApiOperation(value="井口-添加", notes="井口-添加")
@PostMapping(value = "/add")
public Results<T> add(@Validated @RequestBody KhWellhead khWellhead) {
khWellheadService.add(khWellhead);
return Results.OK("操作成功!");
}
/**
* 编辑
*
* @param khWellhead
* @return
*/
@AutoLog(value = "井口-编辑")
@ApiOperation(value="井口-编辑", notes="井口-编辑")
@PostMapping(value = "/edit")
public Results<T> edit(@Validated @RequestBody KhWellhead khWellhead) {
khWellheadService.editById(khWellhead);
return Results.OK("操作成功!");
}
/**
* 通过id删除
*
* @param map
* @return
*/
@AutoLog(value = "井口-通过id删除")
@ApiOperation(value="井口-通过id删除", notes="井口-通过id删除")
@PostMapping(value = "/delete")
public Results<T> delete(@RequestBody Map<String, String> map) {
if(!map.containsKey("id") || StringUtils.isEmpty(map.get("id"))){
return Results.error("请选择数据!");
}
khWellheadService.deleteById(map.get("id"));
return Results.OK("删除成功!");
}
/**
* 批量删除
*
* @param map
* @return
*/
@AutoLog(value = "井口-批量删除")
@ApiOperation(value="井口-批量删除", notes="井口-批量删除")
@PostMapping(value = "/deleteBatch")
public Results<T> deleteBatch(@RequestBody Map<String, String> map) {
if(!map.containsKey("ids") || StringUtils.isEmpty(map.get("ids"))){
return Results.error("请选择数据!");
}
this.khWellheadService.deleteByIds(Arrays.asList(map.get("ids").split(",")));
return Results.OK("批量删除成功!");
}
/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "井口-通过id查询")
@ApiOperation(value="井口-通过id查询", notes="井口-通过id查询")
@GetMapping(value = "/queryById")
public Results<KhWellhead> queryById(@RequestParam(name="id",required=true) String id) {
KhWellhead khWellhead = khWellheadService.queryById(id);
if(khWellhead==null) {
return Results.error("未找到对应数据");
}
return Results.OK(khWellhead);
}
/**
* 导出excel
*
* @param request
* @param khWellhead
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, KhWellhead khWellhead) {
return super.exportXls(request, khWellhead, KhWellhead.class, "井口");
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Results<KhWellhead> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, KhWellhead.class);
}
}
@@ -0,0 +1,83 @@
package com.jero.modules.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.jero.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/**
* @Description: 设备
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Data
@TableName("kh_device")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="kh_device对象", description="设备")
public class KhDevice implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**设备名称*/
@Excel(name = "设备名称", width = 15)
@ApiModelProperty(value = "设备名称")
private String deviceName;
/**设备类型*/
@Excel(name = "设备类型", width = 15)
@ApiModelProperty(value = "设备类型")
private String deviceType;
/**所属井口*/
@Excel(name = "所属井口", width = 15)
@ApiModelProperty(value = "所属井口")
private String wellheadId;
/**设备描述*/
@Excel(name = "设备描述", width = 15)
@ApiModelProperty(value = "设备描述")
private String deviceDesc;
/**设备sn码*/
@Excel(name = "设备sn码", width = 15)
@ApiModelProperty(value = "设备sn码")
private String deviceSn;
/**设备状态(0离线 1在线 默认在线)*/
@Excel(name = "设备状态(0离线 1在线 默认在线)", width = 15)
@ApiModelProperty(value = "设备状态(0离线 1在线 默认在线)")
private String deviceStatuts;
}
@@ -0,0 +1,75 @@
package com.jero.modules.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.jero.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/**
* @Description: 系统设置
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Data
@TableName("kh_system_setting")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="kh_system_setting对象", description="系统设置")
public class KhSystemSetting implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**服务器ip*/
@Excel(name = "服务器ip", width = 15)
@ApiModelProperty(value = "服务器ip")
private String serverIp;
/**服务器端口*/
@Excel(name = "服务器端口", width = 15)
@ApiModelProperty(value = "服务器端口")
private String serverPort;
/**数据采集协议*/
@Excel(name = "数据采集协议", width = 15)
@ApiModelProperty(value = "数据采集协议")
private String dataAcquisitionProtocol;
/**数据采集周期*/
@Excel(name = "数据采集周期", width = 15)
@ApiModelProperty(value = "数据采集周期")
private String dataAcquisitionCycle;
}
@@ -0,0 +1,75 @@
package com.jero.modules.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.jero.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
/**
* @Description: 井口
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Data
@TableName("kh_wellhead")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="kh_wellhead对象", description="井口")
public class KhWellhead implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "主键")
private String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**所属作业区*/
@Excel(name = "所属作业区", width = 15)
@ApiModelProperty(value = "所属作业区")
private String operateArea;
/**所属井场*/
@Excel(name = "所属井场", width = 15)
@ApiModelProperty(value = "所属井场")
private String wellheadArea;
/**井口类型*/
@Excel(name = "井口类型", width = 15)
@ApiModelProperty(value = "井口类型")
private String wellheadType;
/**井口名称*/
@Excel(name = "井口名称", width = 15)
@ApiModelProperty(value = "井口名称")
private String wellheadName;
}
@@ -0,0 +1,17 @@
package com.jero.modules.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.jero.modules.entity.KhDevice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 设备
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface KhDeviceMapper extends BaseMapper<KhDevice> {
}
@@ -0,0 +1,15 @@
package com.jero.modules.mapper;
import org.apache.ibatis.annotations.Param;
import com.jero.modules.entity.KhSystemSetting;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 系统设置
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface KhSystemSettingMapper extends BaseMapper<KhSystemSetting> {
}
@@ -0,0 +1,17 @@
package com.jero.modules.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.jero.modules.entity.KhWellhead;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: 井口
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface KhWellheadMapper extends BaseMapper<KhWellhead> {
}
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jero.modules.1.mapper.KhDeviceMapper">
<resultMap id="KhDeviceResultMap" type="com.jero.modules.1.entity.KhDevice">
<id column="id" property="id" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="sys_org_code" property="sysOrgCode" />
<result column="device_name" property="deviceName" />
<result column="device_type" property="deviceType" />
<result column="wellhead_id" property="wellheadId" />
<result column="device_desc" property="deviceDesc" />
<result column="device_sn" property="deviceSn" />
<result column="device_statuts" property="deviceStatuts" />
</resultMap>
</mapper>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jero.modules.mapper.KhSystemSettingMapper">
<resultMap id="KhSystemSettingResultMap" type="com.jero.modules.entity.KhSystemSetting">
<id column="id" property="id" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="sys_org_code" property="sysOrgCode" />
<result column="server_ip" property="serverIp" />
<result column="server_port" property="serverPort" />
<result column="data_acquisition_protocol" property="dataAcquisitionProtocol" />
<result column="data_acquisition_cycle" property="dataAcquisitionCycle" />
</resultMap>
</mapper>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jero.modules.1.mapper.KhWellheadMapper">
<resultMap id="KhWellheadResultMap" type="com.jero.modules.1.entity.KhWellhead">
<id column="id" property="id" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="sys_org_code" property="sysOrgCode" />
<result column="operate_area" property="operateArea" />
<result column="wellhead_area" property="wellheadArea" />
<result column="wellhead_type" property="wellheadType" />
<result column="wellhead_name" property="wellheadName" />
</resultMap>
</mapper>
@@ -0,0 +1,76 @@
package com.jero.modules.service;
import com.jero.modules.entity.KhDevice;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/**
* @Description: 设备
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface IKhDeviceService extends IService<KhDevice> {
/**
* 分页查询
*
* @param khDevice
* @param pageNo
* @param pageSize
* @param req
* @return
*/
IPage<KhDevice> queryPage(KhDevice khDevice, Integer pageNo, Integer pageSize, HttpServletRequest req);
/**
* 列表查询
*
* @param khDevice
* @param req
* @return
*/
List<KhDevice> queryList(KhDevice khDevice, HttpServletRequest req);
/**
* 保存
*
* @param khDevice
* @return
*/
void add(KhDevice khDevice);
/**
* 更新
*
* @param khDevice
* @return
*/
void editById(KhDevice khDevice);
/**
* 通过id删除
*
* @param id
* @return
*/
void deleteById(String id);
/**
* 批量删除
*
* @param ids
* @return
*/
void deleteByIds(List<String> ids);
/**
* 通过id查询
*
* @param id
* @return
*/
KhDevice queryById(String id);
}
@@ -0,0 +1,76 @@
package com.jero.modules.service;
import com.jero.modules.entity.KhSystemSetting;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/**
* @Description: 系统设置
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface IKhSystemSettingService extends IService<KhSystemSetting> {
/**
* 分页查询
*
* @param khSystemSetting
* @param pageNo
* @param pageSize
* @param req
* @return
*/
IPage<KhSystemSetting> queryPage(KhSystemSetting khSystemSetting, Integer pageNo, Integer pageSize, HttpServletRequest req);
/**
* 列表查询
*
* @param khSystemSetting
* @param req
* @return
*/
List<KhSystemSetting> queryList(KhSystemSetting khSystemSetting, HttpServletRequest req);
/**
* 保存
*
* @param khSystemSetting
* @return
*/
void add(KhSystemSetting khSystemSetting);
/**
* 更新
*
* @param khSystemSetting
* @return
*/
void editById(KhSystemSetting khSystemSetting);
/**
* 通过id删除
*
* @param id
* @return
*/
void deleteById(String id);
/**
* 批量删除
*
* @param ids
* @return
*/
void deleteByIds(List<String> ids);
/**
* 通过id查询
*
* @param id
* @return
*/
KhSystemSetting queryById(String id);
}
@@ -0,0 +1,76 @@
package com.jero.modules.service;
import com.jero.modules.entity.KhWellhead;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/**
* @Description: 井口
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
public interface IKhWellheadService extends IService<KhWellhead> {
/**
* 分页查询
*
* @param khWellhead
* @param pageNo
* @param pageSize
* @param req
* @return
*/
IPage<KhWellhead> queryPage(KhWellhead khWellhead, Integer pageNo, Integer pageSize, HttpServletRequest req);
/**
* 列表查询
*
* @param khWellhead
* @param req
* @return
*/
List<KhWellhead> queryList(KhWellhead khWellhead, HttpServletRequest req);
/**
* 保存
*
* @param khWellhead
* @return
*/
void add(KhWellhead khWellhead);
/**
* 更新
*
* @param khWellhead
* @return
*/
void editById(KhWellhead khWellhead);
/**
* 通过id删除
*
* @param id
* @return
*/
void deleteById(String id);
/**
* 批量删除
*
* @param ids
* @return
*/
void deleteByIds(List<String> ids);
/**
* 通过id查询
*
* @param id
* @return
*/
KhWellhead queryById(String id);
}
@@ -0,0 +1,118 @@
package com.jero.modules.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jero.modules.entity.KhDevice;
import com.jero.modules.mapper.KhDeviceMapper;
import com.jero.modules.service.IKhDeviceService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jero.common.exception.JeroBootException;
import java.util.List;
import java.util.Date;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.system.query.QueryGenerator;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @Description: 设备
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Service
@Transactional(rollbackFor = JeroBootException.class)
public class KhDeviceServiceImpl extends ServiceImpl<KhDeviceMapper, KhDevice> implements IKhDeviceService {
/**
* 分页查询
*
* @param khDevice
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Override
public IPage<KhDevice> queryPage(KhDevice khDevice, Integer pageNo, Integer pageSize,
HttpServletRequest req) {
QueryWrapper<KhDevice> queryWrapper = QueryGenerator.initQueryWrapper(khDevice, req.getParameterMap());
Page<KhDevice> page = new Page<>(pageNo, pageSize);
return page(page, queryWrapper);
}
/**
* 列表查询
*
* @param khDevice
* @param req
* @return
*/
@Override
public List<KhDevice> queryList(KhDevice khDevice, HttpServletRequest req) {
return list(QueryGenerator.initQueryWrapper(khDevice, req.getParameterMap()));
}
/**
* 保存
*
* @param khDevice
* @return
*/
@Override
public void add(KhDevice khDevice) {
Date now = new Date();
khDevice.setCreateTime(now);
khDevice.setUpdateTime(now);
save(khDevice);
}
/**
* 更新
*
* @param khDevice
* @return
*/
@Override
public void editById(KhDevice khDevice) {
Date now = new Date();
khDevice.setUpdateTime(now);
saveOrUpdate(khDevice);
}
/**
* 通过id删除
*
* @param id
* @return
*/
@Override
public void deleteById(String id) {
removeById(id);
}
/**
* 批量删除
*
* @param ids
* @return
*/
@Override
public void deleteByIds(List<String> ids) {
removeByIds(ids);
}
/**
* 通过id查询
*
* @param id
* @return
*/
@Override
public KhDevice queryById(String id) {
return getById(id);
}
}
@@ -0,0 +1,118 @@
package com.jero.modules.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jero.modules.entity.KhSystemSetting;
import com.jero.modules.mapper.KhSystemSettingMapper;
import com.jero.modules.service.IKhSystemSettingService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jero.common.exception.JeroBootException;
import java.util.List;
import java.util.Date;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.system.query.QueryGenerator;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @Description: 系统设置
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Service
@Transactional(rollbackFor = JeroBootException.class)
public class KhSystemSettingServiceImpl extends ServiceImpl<KhSystemSettingMapper, KhSystemSetting> implements IKhSystemSettingService {
/**
* 分页查询
*
* @param khSystemSetting
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Override
public IPage<KhSystemSetting> queryPage(KhSystemSetting khSystemSetting, Integer pageNo, Integer pageSize,
HttpServletRequest req) {
QueryWrapper<KhSystemSetting> queryWrapper = QueryGenerator.initQueryWrapper(khSystemSetting, req.getParameterMap());
Page<KhSystemSetting> page = new Page<>(pageNo, pageSize);
return page(page, queryWrapper);
}
/**
* 列表查询
*
* @param khSystemSetting
* @param req
* @return
*/
@Override
public List<KhSystemSetting> queryList(KhSystemSetting khSystemSetting, HttpServletRequest req) {
return list(QueryGenerator.initQueryWrapper(khSystemSetting, req.getParameterMap()));
}
/**
* 保存
*
* @param khSystemSetting
* @return
*/
@Override
public void add(KhSystemSetting khSystemSetting) {
Date now = new Date();
khSystemSetting.setCreateTime(now);
khSystemSetting.setUpdateTime(now);
save(khSystemSetting);
}
/**
* 更新
*
* @param khSystemSetting
* @return
*/
@Override
public void editById(KhSystemSetting khSystemSetting) {
Date now = new Date();
khSystemSetting.setUpdateTime(now);
saveOrUpdate(khSystemSetting);
}
/**
* 通过id删除
*
* @param id
* @return
*/
@Override
public void deleteById(String id) {
removeById(id);
}
/**
* 批量删除
*
* @param ids
* @return
*/
@Override
public void deleteByIds(List<String> ids) {
removeByIds(ids);
}
/**
* 通过id查询
*
* @param id
* @return
*/
@Override
public KhSystemSetting queryById(String id) {
return getById(id);
}
}
@@ -0,0 +1,118 @@
package com.jero.modules.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jero.modules.entity.KhWellhead;
import com.jero.modules.mapper.KhWellheadMapper;
import com.jero.modules.service.IKhWellheadService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jero.common.exception.JeroBootException;
import java.util.List;
import java.util.Date;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.system.query.QueryGenerator;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @Description: 井口
* @Author: jero-boot
* @Date: 2024-04-01
* @Version: V1.0
*/
@Service
@Transactional(rollbackFor = JeroBootException.class)
public class KhWellheadServiceImpl extends ServiceImpl<KhWellheadMapper, KhWellhead> implements IKhWellheadService {
/**
* 分页查询
*
* @param khWellhead
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@Override
public IPage<KhWellhead> queryPage(KhWellhead khWellhead, Integer pageNo, Integer pageSize,
HttpServletRequest req) {
QueryWrapper<KhWellhead> queryWrapper = QueryGenerator.initQueryWrapper(khWellhead, req.getParameterMap());
Page<KhWellhead> page = new Page<>(pageNo, pageSize);
return page(page, queryWrapper);
}
/**
* 列表查询
*
* @param khWellhead
* @param req
* @return
*/
@Override
public List<KhWellhead> queryList(KhWellhead khWellhead, HttpServletRequest req) {
return list(QueryGenerator.initQueryWrapper(khWellhead, req.getParameterMap()));
}
/**
* 保存
*
* @param khWellhead
* @return
*/
@Override
public void add(KhWellhead khWellhead) {
Date now = new Date();
khWellhead.setCreateTime(now);
khWellhead.setUpdateTime(now);
save(khWellhead);
}
/**
* 更新
*
* @param khWellhead
* @return
*/
@Override
public void editById(KhWellhead khWellhead) {
Date now = new Date();
khWellhead.setUpdateTime(now);
saveOrUpdate(khWellhead);
}
/**
* 通过id删除
*
* @param id
* @return
*/
@Override
public void deleteById(String id) {
removeById(id);
}
/**
* 批量删除
*
* @param ids
* @return
*/
@Override
public void deleteByIds(List<String> ids) {
removeByIds(ids);
}
/**
* 通过id查询
*
* @param id
* @return
*/
@Override
public KhWellhead queryById(String id) {
return getById(id);
}
}
@@ -1,5 +1,5 @@
server:
port: 8080
port: 9393
tomcat:
max-swallow-size: -1
error:
@@ -131,7 +131,7 @@ spring:
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000;druid.stat.logSlowSql\=true
datasource:
master:
url: jdbc:mysql://10.10.10.44:3306/jero-boot-bug?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://10.10.10.44:3306/kh_advice?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: hzwlsoft.com
driver-class-name: com.mysql.cj.jdbc.Driver
@@ -272,13 +272,13 @@ jero:
# 文件限制后缀黑名单
fileSuffixLimits : 0x00,%00,\\00,.jsp,.exe,.php,.asp,.aspx,.jspx,.xml,.html,.js,.sh,.bin,$DATA
# 跨站白名单
whiteUrls: localhost:3000,localhost:8080
whiteUrls: localhost:3000,localhost:8080,localhost:4242,localhost:9393
# xss白名单
xssExcludedPages: /login,/updatePassword
# cors白名单
notFilter:
# origin地址
originIp: http://localhost:3000,http://localhost:8080
originIp: http://localhost:3000,http://localhost:8080,http://localhost:4242,http://localhost:9393
# 加密默认值
password:
pbe:
@@ -1,60 +0,0 @@
[{
"id": "jero-system",
"order": 0,
"predicates": [{
"name": "Path",
"args": {
"_genkey_0": "/sys/**",
"_genkey_1": "/eoa/**",
"_genkey_2": "/joa/**",
"_genkey_3": "/jmreport/**",
"_genkey_4": "/bigscreen/**",
"_genkey_5": "/desform/**",
"_genkey_6": "/online/**",
"_genkey_8": "/act/**",
"_genkey_9": "/plug-in/**",
"_genkey_10": "/generic/**",
"_genkey_11": "/v1/**"
}
}],
"filters": [],
"uri": "lb://jero-system"
}, {
"id": "jero-demo",
"order": 1,
"predicates": [{
"name": "Path",
"args": {
"_genkey_0": "/mock/**",
"_genkey_1": "/test/**",
"_genkey_2": "/bigscreen/template1/**",
"_genkey_3": "/bigscreen/template2/**"
}
}],
"filters": [],
"uri": "lb://jero-demo"
}, {
"id": "jero-system-websocket",
"order": 2,
"predicates": [{
"name": "Path",
"args": {
"_genkey_0": "/websocket/**",
"_genkey_1": "/eoaSocket/**",
"_genkey_2": "/newsWebsocket/**"
}
}],
"filters": [],
"uri": "lb:ws://jero-system"
}, {
"id": "jero-demo-websocket",
"order": 3,
"predicates": [{
"name": "Path",
"args": {
"_genkey_0": "/vxeSocket/**"
}
}],
"filters": [],
"uri": "lb:ws://jero-demo"
}]
@@ -1,321 +0,0 @@
# 标准配置的模板,可自行删减
server:
tomcat:
max-swallow-size: -1
error:
include-exception: true
include-stacktrace: ALWAYS
include-message: ALWAYS
compression:
enabled: true
min-response-size: 1024
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
health:
mail:
enabled: false
endpoints:
web:
exposure:
include: "*" #暴露所有节点
health:
sensitive: true #关闭过滤敏感信息
endpoint:
health:
show-details: ALWAYS #显示详细信息
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
mail:
host: smtp.163.com
username: test@163.com
password: ??
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
## quartz定时任务,采用数据库方式
quartz:
job-store-type: jdbc
initialize-schema: embedded
#定时任务启动开关,true-开 false-关
auto-startup: true
#启动时更新己存在的Job
overwrite-existing-jobs: true
properties:
org:
quartz:
scheduler:
instanceName: MyScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
misfireThreshold: 60000
clusterCheckinInterval: 10000
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#json 时间戳统一转换
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
jpa:
open-in-view: false
activiti:
check-process-definitions: false
#启用作业执行器
async-executor-activate: false
#启用异步执行器
job-executor-activate: false
aop:
proxy-target-class: true
#配置freemarker
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
prefer-file-system-access: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径,js,css等
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/,classpath:/public/
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: druid
loginPassword: druid
allow:
web-stat-filter:
enabled: true
dynamic:
druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000;druid.stat.logSlowSql\=true
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/jero-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/jero-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# 多数据源配置
#multi-datasource1:
#url: jdbc:mysql://localhost:3306/jero-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
#username: root
#password: root
#driver-class-name: com.mysql.cj.jdbc.Driver
#redis 配置
redis:
database: 3
host: 121.36.69.172
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: 'hzwlsoft.com'
port: 4780
#rabbitmq 配置
rabbitmq:
host: 121.36.69.172
username: admin
password: hzwlsoft.com
port: 5672
publisher-confirm-type: correlated
publisher-returns: true
virtual-host: /
listener:
simple:
acknowledge-mode: manual
#消费者的最小数量
concurrency: 1
#消费者的最大数量
max-concurrency: 1
#是否支持重试
retry:
enabled: true
#mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:com/jero/**/xml/*Mapper.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
#主键类型 0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
id-type: ASSIGN_ID
# 默认数据库表下划线命名
table-underline: true
configuration:
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 返回类型为Map,显示null对应的字段
call-setters-on-nulls: true
#jero专用配置
jero :
# 签名密钥串(前后端要一致,正式发布请自行修改)
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
# 本地:local\Miniominio\阿里云:alioss
uploadType: local
path :
#文件上传根目录 设置
upload: G://opt//upFiles
#webapp文件路径
webapp: G://opt//webapp
shiro:
excludeUrls: /test/jeroDemo/demo3,/test/jeroDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
#阿里云oss存储配置
oss:
endpoint: oss-cn-beijing.aliyuncs.com
accessKey: ??
secretKey: ??
bucketName: jeroos
staticDomain: jerodev
# ElasticSearch 6设置
elasticsearch:
cluster-name: jero-ES
cluster-nodes: 127.0.0.1:9200
check-enabled: false
# 表单设计器配置
desform:
# 主题颜色(仅支持 16进制颜色代码)
theme-color: "#1890ff"
# 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
upload-type: system
# 在线预览文件服务器地址配置
file-view-domain: 127.0.0.1:8012
# minio文件上传
minio:
minio_url: http://minio.jero.com
minio_name: ??
minio_pass: ??
bucketName: otatest
#大屏报表参数设置
jmreport:
mode: dev
#数据字典是否可以全局看到
saas: false
#是否需要校验token
is_verify_token: false
#必须校验方法
verify_methods: remove,delete,save,add,update
#Wps在线文档
wps:
domain: https://wwo.wps.cn/office/
appid: ??
appsecret: ??
#xxl-job配置
xxljob:
enabled: false
adminAddresses: http://127.0.0.1:9080/xxl-job-admin
appname: ${spring.application.name}
accessToken: ''
address: 127.0.0.1:30007
ip: 127.0.0.1
port: 30007
logPath: logs/jero/job/jobhandler/
logRetentionDays: 30
route:
config:
data-id: jero-gateway-router
group: DEFAULT_GROUP
#自定义路由配置 yml nacos database
data-type: yml
#分布式锁配置
redisson:
address: 121.36.69.172:4780
password: 'hzwlsoft.com'
type: STANDALONE
enabled: true
# 文件限制后缀黑名单
fileSuffixLimits : 0x00,%00,\\00,.jsp,.exe,.php,.asp,.aspx,.jspx,.xml,.html,.js,.sh,.bin
# 跨站白名单
whiteUrls:
#cas单点登录
cas:
prefixUrl: http://cas.example.org:8443/cas
#Mybatis输出sql日志
logging:
level:
com.jero.modules.system.mapper : info
#swagger
knife4j:
#开启增强配置
enable: true
#开启生产环境屏蔽
production: false
basic:
enable: false
username: jero
password: jero.com
#第三方登录
justauth:
enabled: true
type:
GITHUB:
client-id: true
client-secret: true
redirect-uri: http://sso.test.com:8080/jero-boot/sys/thirdLogin/github/callback
WECHAT_ENTERPRISE:
client-id: true
client-secret: true
redirect-uri: http://sso.test.com:8080/jero-boot/sys/thirdLogin/wechat_enterprise/callback
agent-id: 1000002
DINGTALK:
client-id: true
client-secret: true
redirect-uri: http://sso.test.com:8080/jero-boot/sys/thirdLogin/dingtalk/callback
WECHAT_OPEN:
client-id: ??
client-secret: ??
redirect-uri: http://sso.test.com:8080/jero-boot/sys/thirdLogin/wechat_open/callback
cache:
type: default
prefix: 'demo::'
timeout: 1h
@@ -1,58 +0,0 @@
<?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>jero-boot-starter</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-boot-starter-cloud</artifactId>
<dependencies>
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>jero-system-cloud-api</artifactId>
</dependency>
<!-- Nacos注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Nacos配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Nacos 2.0客户端 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.0.4</version>
</dependency>
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 服务降级 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,170 +0,0 @@
package com.jero.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
import feign.Feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.config.mqtoken.UserTokenContext;
import com.jero.common.constant.CommonConstant;
import com.jero.common.util.DateUtils;
import com.jero.common.util.PathMatcherUtil;
import com.jero.config.sign.interceptor.SignAuthConfiguration;
import com.jero.config.sign.util.HttpUtils;
import com.jero.config.sign.util.SignUtil;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@Slf4j
@Configuration
public class FeignConfig {
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
log.debug("Feign request: {}", request.getRequestURI());
// 将token信息放入header中
String token = getToken(request);
log.debug("Feign request token: {}", token);
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
//根据URL地址过滤请求 【字典表参数签名验证】
if (PathMatcherUtil.matches(Arrays.asList(SignAuthConfiguration.urlList),requestTemplate.path())) {
try {
log.info("============================ [begin] fegin starter url ============================");
log.info(requestTemplate.path());
log.info(requestTemplate.method());
String queryLine = requestTemplate.queryLine();
queryLine = getQueryLine(queryLine);
log.info(queryLine);
if(requestTemplate.body()!=null){
log.info(new String(requestTemplate.body()));
}
SortedMap<String, String> allParams = HttpUtils.getAllParams(requestTemplate.path(),queryLine,requestTemplate.body(),requestTemplate.method());
String sign = SignUtil.getParamsSign(allParams);
log.info(" Feign request params sign: {}",sign);
log.info("============================ [end] fegin starter url ============================");
requestTemplate.header(CommonConstant.X_SIGN, sign);
requestTemplate.header(CommonConstant.X_TIMESTAMP, DateUtils.getCurrentTimestamp().toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
String token = UserTokenContext.getToken();
log.debug("Feign request token: {}", token);
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
}
};
}
private String getQueryLine(String queryLine) {
if(queryLine!=null && queryLine.startsWith("?")){
queryLine = queryLine.substring(1);
}
return queryLine;
}
private String getToken(HttpServletRequest request) {
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
if(token==null || "".equals(token)){
token = request.getParameter("token");
}
return token;
}
/**
* Feign 客户端的日志记录,默认级别为NONE
* Logger.Level 的具体级别如下:
* NONE:不记录任何信息
* BASIC:仅记录请求方法、URL以及响应状态码和执行时间
* HEADERS:除了记录 BASIC级别的信息外,还会记录请求和响应的头信息
* FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
/**
* Feign支持文件上传
* @param messageConverters
* @return
*/
@Bean
@Primary
@Scope("prototype")
public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
// update-begin--Author:sunjianlei Date:20210604 for 给 Feign 添加 FastJson 的解析支持 ----------
@Bean
public Encoder feignEncoder() {
return new SpringEncoder(feignHttpMessageConverter());
}
@Bean
public Decoder feignDecoder() {
return new SpringDecoder(feignHttpMessageConverter());
}
/**
* 设置解码器为fastjson
*
* @return
*/
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(this.getFastJsonConverter());
return () -> httpMessageConverters;
}
private FastJsonHttpMessageConverter getFastJsonConverter() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
List<MediaType> supportedMediaTypes = new ArrayList<>();
MediaType mediaTypeJson = MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE);
supportedMediaTypes.add(mediaTypeJson);
converter.setSupportedMediaTypes(supportedMediaTypes);
FastJsonConfig config = new FastJsonConfig();
config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
converter.setFastJsonConfig(config);
return converter;
}
// update-end--Author:sunjianlei Date:20210604 for 给 Feign 添加 FastJson 的解析支持 ----------
}
@@ -1,24 +0,0 @@
package com.jero.starter.cloud.config;
import feign.Client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PersonBeanConfiguration {
/**
* 创建FeignClient
*/
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null),
cachingFactory, clientFactory);
}
}
@@ -1,6 +0,0 @@
package com.jero.starter.cloud.feign;
public interface IJeroFeignService {
<T> T newInstance(Class<T> apiType, String name);
}
@@ -1,62 +0,0 @@
package com.jero.starter.cloud.feign.impl;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.codec.Decoder;
import feign.codec.Encoder;
import lombok.extern.slf4j.Slf4j;
import com.jero.common.constant.CommonConstant;
import com.jero.starter.cloud.feign.IJeroFeignService;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Service
@Slf4j
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@Import(FeignClientsConfiguration.class)
public class JeroFeignService implements IJeroFeignService {
//Feign 原生构造器
Feign.Builder builder;
//创建构造器
public JeroFeignService(Decoder decoder, Encoder encoder, Client client, Contract contract) {
this.builder = Feign.builder()
.client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract);
builder.requestInterceptor(requestTemplate -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (null != attributes) {
HttpServletRequest request = attributes.getRequest();
log.info("Feign request: {}", request.getRequestURI());
// 将token信息放入header中
String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
if(token==null){
token = request.getParameter("token");
}
log.info("Feign request token: {}", token);
requestTemplate.header(CommonConstant.X_ACCESS_TOKEN, token);
}
});
}
@Override
public <T> T newInstance(Class<T> clientClass, String serviceName) {
return builder.target(clientClass, String.format("http://%s/", serviceName));
}
}
@@ -1,21 +0,0 @@
<?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>jero-boot-starter</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-boot-starter-job</artifactId>
<description>jero-boot-starter-定时任务</description>
<dependencies>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job-core.version}</version>
</dependency>
</dependencies>
</project>
@@ -1,46 +0,0 @@
package com.jero.boot.starter.job.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import com.jero.boot.starter.job.prop.XxlJobProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* 定时任务配置
*/
@Slf4j
@Configuration
@EnableConfigurationProperties(value = XxlJobProperties.class)
@ConditionalOnProperty(value = "jero.xxljob.enabled", havingValue = "true", matchIfMissing = true)
public class XxlJobConfiguration {
@Resource
private XxlJobProperties xxlJobProperties;
//@Bean(initMethod = "start", destroyMethod = "destroy")
@Bean
@ConditionalOnClass()
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());
xxlJobSpringExecutor.setAppname(xxlJobProperties.getAppname());
// xxlJobSpringExecutor.setIp(xxlJobProperties.getIp());
// xxlJobSpringExecutor.setPort(xxlJobProperties.getPort());
xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());
xxlJobSpringExecutor.setLogPath(xxlJobProperties.getLogPath());
xxlJobSpringExecutor.setLogRetentionDays(xxlJobProperties.getLogRetentionDays());
return xxlJobSpringExecutor;
}
}
@@ -1,35 +0,0 @@
package com.jero.boot.starter.job.prop;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "jero.xxljob")
public class XxlJobProperties {
private String adminAddresses;
private String appname;
private String ip;
private int port;
private String accessToken;
private String logPath;
private int logRetentionDays;
/**
* 是否开启xxljob
*/
private Boolean enable = true;
}
@@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.jero.boot.starter.job.config.XxlJobConfiguration
@@ -1,37 +0,0 @@
<?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>jero-boot-starter</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-boot-starter-lock</artifactId>
<description>jero-boot-starter-分布式锁</description>
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,57 +0,0 @@
package com.jero.boot.starter.lock.annotation;
import com.jero.boot.starter.lock.enums.LockModel;
import java.lang.annotation.*;
/**
* Redisson分布式锁注解
*
* @author zyf
* @date 2020-11-11
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface JLock {
/**
* 锁的模式:如果不设置,自动模式,当参数只有一个.使用 REENTRANT 参数多个 MULTIPLE
*/
LockModel lockModel() default LockModel.AUTO;
/**
* 如果keys有多个,如果不设置,则使用 联锁
* @return
*/
String[] lockKey() default {};
/**
* key的静态常量:当key的spel的值是LIST,数组时使用+号连接将会被spel认为这个变量是个字符串
* @return
*/
String keyConstant() default "";
/**
* 锁超时时间,默认30000毫秒
*
* @return int
*/
long expireSeconds() default 30000L;
/**
* 等待加锁超时时间,默认10000毫秒 -1 则表示一直等待
*
* @return int
*/
long waitTime() default 10000L;
/**
* 未取到锁时提示信息
*
* @return
*/
String failMsg() default "获取锁失败,请稍后重试";
}
@@ -1,36 +0,0 @@
package com.jero.boot.starter.lock.annotation;
/**
* @author zyf
*/
import java.lang.annotation.*;
/**
* 防止重复提交的注解
*
* @author 2019年6月18日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface JRepeat {
/**
* 超时时间
*
* @return
*/
int lockTime();
/**
* redis 锁key的
*
* @return redis 锁key
*/
String lockKey() default "";
}
@@ -1,72 +0,0 @@
package com.jero.boot.starter.lock.annotation;
/**
* @author zyf
* @date 2019/10/26 18:26
*/
/**
* 分布式锁枚举类
* @author zyf
*/
public enum LockConstant {
/**
* 通用锁常量
*/
COMMON("commonLock:", 1, 500, "请勿重复点击");
/**
* 分布式锁前缀
*/
private String keyPrefix;
/**
* 等到最大时间,强制获取锁
*/
private int waitTime;
/**
* 锁失效时间
*/
private int leaseTime;
/**
* 加锁提示
*/
private String message;
LockConstant(String keyPrefix, int waitTime, int leaseTime, String message) {
this.keyPrefix = keyPrefix;
this.waitTime = waitTime;
this.leaseTime = leaseTime;
this.message = message;
}
public String getKeyPrefix() {
return keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
public int getWaitTime() {
return waitTime;
}
public void setWaitTime(int waitTime) {
this.waitTime = waitTime;
}
public int getLeaseTime() {
return leaseTime;
}
public void setLeaseTime(int leaseTime) {
this.leaseTime = leaseTime;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@@ -1,67 +0,0 @@
package com.jero.boot.starter.lock.aspect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.util.ArrayList;
import java.util.List;
/**
* @author zyf
*/
@Slf4j
public class BaseAspect {
/**
* 通过spring SpEL 获取参数
*
* @param key 定义的key值 以#开头 例如:#user
* @param parameterNames 形参
* @param values 形参值
* @param keyConstant key的常亮
* @return
*/
public List<String> getValueBySpEL(String key, String[] parameterNames, Object[] values, String keyConstant) {
List<String> keys = new ArrayList<>();
if (!key.contains("#")) {
String s = "redis:lock:" + key + keyConstant;
log.info("lockKey:" + s);
keys.add(s);
return keys;
}
//spel解析器
ExpressionParser parser = new SpelExpressionParser();
//spel上下文
EvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], values[i]);
}
Expression expression = parser.parseExpression(key);
Object value = expression.getValue(context);
if (value != null) {
if (value instanceof List) {
List<Object> value1 = (List) value;
for (Object o : value1) {
addKeys(keys, o, keyConstant);
}
} else if (value.getClass().isArray()) {
Object[] obj = (Object[]) value;
for (Object o : obj) {
addKeys(keys, o, keyConstant);
}
} else {
addKeys(keys, value, keyConstant);
}
}
log.info("表达式key={},value={}", key, keys);
return keys;
}
private void addKeys(List<String> keys, Object o, String keyConstant) {
keys.add("redis:lock:" + o.toString() + keyConstant);
}
}
@@ -1,166 +0,0 @@
package com.jero.boot.starter.lock.aspect;
import com.jero.boot.starter.lock.annotation.JLock;
import com.jero.boot.starter.lock.enums.LockModel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.RedissonMultiLock;
import org.redisson.RedissonRedLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁解析器
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
@Aspect
@Component
public class DistributedLockHandler extends BaseAspect{
@Autowired(required = false)
private RedissonClient redissonClient;
/**
* 切面环绕通知
*
* @param joinPoint
* @param jLock
* @return Object
*/
@SneakyThrows
@Around("@annotation(jLock)")
public Object around(ProceedingJoinPoint joinPoint, JLock jLock) {
Object obj = null;
RLock rLock = getLock(joinPoint, jLock);
boolean res = false;
//获取超时时间
long expireSeconds = jLock.expireSeconds();
//等待多久,n秒内获取不到锁,则直接返回
long waitTime = jLock.waitTime();
//执行aop
if (rLock != null) {
try {
if (waitTime == -1) {
res = true;
//一直等待加锁
rLock.lock(expireSeconds, TimeUnit.MILLISECONDS);
} else {
res = rLock.tryLock(waitTime, expireSeconds, TimeUnit.MILLISECONDS);
}
if (res) {
obj = joinPoint.proceed();
} else {
log.error("获取锁异常");
}
} finally {
if (res) {
rLock.unlock();
}
}
}
log.info("结束RedisLock环绕通知...");
return obj;
}
@SneakyThrows
private RLock getLock(ProceedingJoinPoint joinPoint, JLock jLock) {
String[] keys = jLock.lockKey();
if (keys.length == 0) {
throw new IllegalArgumentException("keys不能为空");
}
String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(((MethodSignature) joinPoint.getSignature()).getMethod());
Object[] args = joinPoint.getArgs();
LockModel lockModel = jLock.lockModel();
if (!lockModel.equals(LockModel.MULTIPLE) && !lockModel.equals(LockModel.REDLOCK) && keys.length > 1) {
throw new IllegalArgumentException("参数有多个,锁模式为->" + lockModel.name() + ".无法锁定");
}
RLock rLock = null;
String keyConstant = jLock.keyConstant();
lockModel = getLockModel(keys, lockModel);
switch (lockModel) {
case FAIR:
rLock = redissonClient.getFairLock(getValueBySpEL(keys[0], parameterNames, args, keyConstant).get(0));
break;
case REDLOCK:
List<RLock> rLocks = new ArrayList<>();
getRedLock(keys, parameterNames, args, keyConstant, rLocks);
RLock[] locks = new RLock[rLocks.size()];
int index = 0;
for (RLock r : rLocks) {
locks[index++] = r;
}
rLock = new RedissonRedLock(locks);
break;
case MULTIPLE:
rLocks = new ArrayList<>();
getRedLock(keys, parameterNames, args, keyConstant, rLocks);
locks = new RLock[rLocks.size()];
index = 0;
for (RLock r : rLocks) {
locks[index++] = r;
}
rLock = new RedissonMultiLock(locks);
break;
case REENTRANT:
List<String> valueBySpEL = getValueBySpEL(keys[0], parameterNames, args, keyConstant);
//如果spel表达式是数组或者LIST 则使用红锁
if (valueBySpEL.size() == 1) {
rLock = redissonClient.getLock(valueBySpEL.get(0));
} else {
locks = new RLock[valueBySpEL.size()];
index = 0;
for (String s : valueBySpEL) {
locks[index++] = redissonClient.getLock(s);
}
rLock = new RedissonRedLock(locks);
}
break;
case READ:
rLock = redissonClient.getReadWriteLock(getValueBySpEL(keys[0], parameterNames, args, keyConstant).get(0)).readLock();
break;
case WRITE:
rLock = redissonClient.getReadWriteLock(getValueBySpEL(keys[0], parameterNames, args, keyConstant).get(0)).writeLock();
break;
default: break;
}
return rLock;
}
private LockModel getLockModel(String[] keys, LockModel lockModel) {
if (lockModel.equals(LockModel.AUTO)) {
if (keys.length > 1) {
lockModel = LockModel.REDLOCK;
} else {
lockModel = LockModel.REENTRANT;
}
}
return lockModel;
}
private void getRedLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, List<RLock> rLocks) {
for (String key : keys) {
List<String> valueBySpEL = getValueBySpEL(key, parameterNames, args, keyConstant);
for (String s : valueBySpEL) {
rLocks.add(redissonClient.getLock(s));
}
}
}
}
@@ -1,80 +0,0 @@
package com.jero.boot.starter.lock.aspect;
/**
* @author zyf
*/
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import com.jero.boot.starter.lock.annotation.JRepeat;
import com.jero.boot.starter.lock.client.RedissonLockClient;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 防止重复提交分布式锁拦截器
*
* @author 2019年6月18日
*/
@Aspect
@Component
public class RepeatSubmitAspect extends BaseAspect{
@Resource
private RedissonLockClient redissonLockClient;
/***
* 定义controller切入点拦截规则,拦截JRepeat注解的业务方法
*/
@Pointcut("@annotation(jRepeat)")
public void pointCut(JRepeat jRepeat) {
// do point
}
/**
* AOP分布式锁拦截
*
* @param joinPoint
* @return
* @throws Exception
*/
@Around("pointCut(jRepeat)")
public Object repeatSubmit(ProceedingJoinPoint joinPoint,JRepeat jRepeat) throws Throwable {
String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(((MethodSignature) joinPoint.getSignature()).getMethod());
if (Objects.nonNull(jRepeat)) {
// 获取参数
Object[] args = joinPoint.getArgs();
// 进行一些参数的处理,比如获取订单号,操作人id等
String key =getValueBySpEL(jRepeat.lockKey(), parameterNames, args,"RepeatSubmit").get(0);
// 公平加锁,lockTime后锁自动释放
boolean isLocked = false;
try {
isLocked = redissonLockClient.fairLock(key, TimeUnit.SECONDS, jRepeat.lockTime());
// 如果成功获取到锁就继续执行
if (isLocked) {
// 执行进程
return joinPoint.proceed();
} else {
// 未获取到锁
throw new IllegalArgumentException("请勿重复提交");
}
} finally {
// 如果锁还存在,在方法执行完成后,释放锁
if (isLocked) {
redissonLockClient.unlock(key);
}
}
}
return joinPoint.proceed();
}
}
@@ -1,143 +0,0 @@
package com.jero.boot.starter.lock.client;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁实现基于Redisson
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
@Component
public class RedissonLockClient {
@Autowired
private RedissonClient redissonClient;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 获取锁
*/
public RLock getLock(String lockKey) {
return redissonClient.getLock(lockKey);
}
/**
* 加锁操作
*
* @return boolean
*/
public boolean tryLock(String lockName, long expireSeconds) {
return tryLock(lockName, 0, expireSeconds);
}
/**
* 加锁操作
*
* @return boolean
*/
public boolean tryLock(String lockName, long waitTime, long expireSeconds) {
RLock rLock = getLock(lockName);
boolean getLock = false;
try {
getLock = rLock.tryLock(waitTime, expireSeconds, TimeUnit.SECONDS);
if (getLock) {
log.info("获取锁成功,lockName={}", lockName);
} else {
log.info("获取锁失败,lockName={}", lockName);
}
} catch (InterruptedException e) {
log.error("获取式锁异常,lockName=" + lockName, e);
Thread.currentThread().interrupt();
}finally {
rLock.unlock();
}
return getLock;
}
public boolean fairLock(String lockKey, TimeUnit unit, int leaseTime) {
RLock fairLock = redissonClient.getFairLock(lockKey);
try {
boolean existKey = existKey(lockKey);
// 已经存在了,就直接返回
if (existKey) {
return false;
}
return fairLock.tryLock(3, leaseTime, unit);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}finally {
fairLock.unlock();
}
return false;
}
public boolean existKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 锁lockKey
*
* @param lockKey
* @return
*/
public RLock lock(String lockKey) {
RLock lock = getLock(lockKey);
try {
lock.lock();
}catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
return lock;
}
/**
* 锁lockKey
*
* @param lockKey
* @param leaseTime
* @return
*/
public RLock lock(String lockKey, long leaseTime) {
RLock lock = getLock(lockKey);
try {
lock.lock(leaseTime, TimeUnit.SECONDS);
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
return lock;
}
/**
* 解锁
*
* @param lockName 锁名称
*/
public void unlock(String lockName) {
try {
redissonClient.getLock(lockName).unlock();
} catch (Exception e) {
log.error("解锁异常,lockName=" + lockName, e);
}
}
}
@@ -1,36 +0,0 @@
package com.jero.boot.starter.lock.config;
import lombok.extern.slf4j.Slf4j;
import com.jero.boot.starter.lock.core.RedissonManager;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import org.redisson.api.RedissonClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Redisson自动化配置
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
@Configuration
@ConditionalOnClass(RedissonProperties.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonConfiguration {
@Bean
@ConditionalOnMissingBean(RedissonClient.class)
public RedissonClient redissonClient(RedissonProperties redissonProperties) {
RedissonManager redissonManager = new RedissonManager(redissonProperties);
log.info("RedissonManager初始化完成,当前连接方式:" + redissonProperties.getType() + ",连接地址:" + redissonProperties.getAddress());
return redissonManager.getRedisson();
}
}
@@ -1,98 +0,0 @@
package com.jero.boot.starter.lock.core;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import com.jero.boot.starter.lock.core.strategy.RedissonConfigStrategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import com.jero.boot.starter.lock.core.strategy.impl.ClusterRedissonConfigStrategyImpl;
import com.jero.boot.starter.lock.core.strategy.impl.MasterslaveRedissonConfigStrategyImpl;
import com.jero.boot.starter.lock.core.strategy.impl.SentinelRedissonConfigStrategyImpl;
import com.jero.boot.starter.lock.core.strategy.impl.StandaloneRedissonConfigStrategyImpl;
import com.jero.boot.starter.lock.enums.RedisConnectionType;
import org.redisson.Redisson;
import org.redisson.config.Config;
/**
* Redisson配置管理器,用于初始化的redisson实例
*
* @author zyf
* @date 2020-11-12
*/
@Slf4j
public class RedissonManager {
private Config config = new Config();
private Redisson redisson = null;
public RedissonManager() {
}
public RedissonManager(RedissonProperties redissonProperties) {
//装配开关
Boolean enabled = redissonProperties.getEnabled();
if (enabled != null && enabled) {
try {
config = RedissonConfigFactory.getInstance().createConfig(redissonProperties);
redisson = (Redisson) Redisson.create(config);
} catch (Exception e) {
log.error("Redisson初始化错误", e);
}
}
}
public Redisson getRedisson() {
return redisson;
}
/**
* Redisson连接方式配置工厂
* 双重检查锁
*/
static class RedissonConfigFactory {
private RedissonConfigFactory() {
}
private static RedissonConfigFactory factory = null;
public static RedissonConfigFactory getInstance() {
synchronized (Object.class) {
if (factory == null) {
factory = new RedissonConfigFactory();
}
}
return factory;
}
/**
* 根据连接类型創建连接方式的配置
*
* @param redissonProperties
* @return Config
*/
Config createConfig(RedissonProperties redissonProperties) {
Preconditions.checkNotNull(redissonProperties);
Preconditions.checkNotNull(redissonProperties.getAddress(), "redis地址未配置");
RedisConnectionType connectionType = redissonProperties.getType();
// 声明连接方式
RedissonConfigStrategy redissonConfigStrategy;
if (connectionType.equals(RedisConnectionType.SENTINEL)) {
redissonConfigStrategy = new SentinelRedissonConfigStrategyImpl();
} else if (connectionType.equals(RedisConnectionType.CLUSTER)) {
redissonConfigStrategy = new ClusterRedissonConfigStrategyImpl();
} else if (connectionType.equals(RedisConnectionType.MASTERSLAVE)) {
redissonConfigStrategy = new MasterslaveRedissonConfigStrategyImpl();
} else {
redissonConfigStrategy = new StandaloneRedissonConfigStrategyImpl();
}
Preconditions.checkNotNull(redissonConfigStrategy, "连接方式创建异常");
return redissonConfigStrategy.createRedissonConfig(redissonProperties);
}
}
}
@@ -1,21 +0,0 @@
package com.jero.boot.starter.lock.core.strategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import org.redisson.config.Config;
/**
* Redisson配置构建接口
*
* @author zyf
* @date 2020-11-11
*/
public interface RedissonConfigStrategy {
/**
* 根据不同的Redis配置策略创建对应的Config
*
* @param redissonProperties
* @return Config
*/
Config createRedissonConfig(RedissonProperties redissonProperties);
}
@@ -1,43 +0,0 @@
package com.jero.boot.starter.lock.core.strategy.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.jero.boot.starter.lock.core.strategy.RedissonConfigStrategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import com.jero.boot.starter.lock.enums.GlobalConstant;
import org.redisson.config.Config;
/**
* 集群方式Redisson配置
* cluster方式至少6个节点(3主3从)
* 配置方式:127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6383,127.0.0.1:6384
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
public class ClusterRedissonConfigStrategyImpl implements RedissonConfigStrategy {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
String[] addrTokens = address.split(",");
// 设置集群(cluster)节点的服务IP和端口
for (int i = 0; i < addrTokens.length; i++) {
config.useClusterServers().addNodeAddress(GlobalConstant.REDIS_CONNECTION_PREFIX + addrTokens[i]);
if (StringUtils.isNotBlank(password)) {
config.useClusterServers().setPassword(password);
}
}
log.info("初始化集群方式Config,连接地址:" + address);
} catch (Exception e) {
log.error("集群Redisson初始化错误", e);
e.printStackTrace();
}
return config;
}
}
@@ -1,54 +0,0 @@
package com.jero.boot.starter.lock.core.strategy.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.jero.boot.starter.lock.core.strategy.RedissonConfigStrategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import com.jero.boot.starter.lock.enums.GlobalConstant;
import org.redisson.config.Config;
import java.util.ArrayList;
import java.util.List;
/**
* 主从方式Redisson配置
* <p>配置方式: 127.0.0.1:6379(主),127.0.0.1:6380(子),127.0.0.1:6381(子)</p>
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
public class MasterslaveRedissonConfigStrategyImpl implements RedissonConfigStrategy {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
int database = redissonProperties.getDatabase();
String[] addrTokens = address.split(",");
String masterNodeAddr = addrTokens[0];
// 设置主节点ip
config.useMasterSlaveServers().setMasterAddress(masterNodeAddr);
if (StringUtils.isNotBlank(password)) {
config.useMasterSlaveServers().setPassword(password);
}
config.useMasterSlaveServers().setDatabase(database);
// 设置从节点,移除第一个节点,默认第一个为主节点
List<String> slaveList = new ArrayList<>();
for (String addrToken : addrTokens) {
slaveList.add(GlobalConstant.REDIS_CONNECTION_PREFIX + addrToken);
}
slaveList.remove(0);
config.useMasterSlaveServers().addSlaveAddress(slaveList.toArray(new String[0]));
log.info("初始化主从方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("主从Redisson初始化错误", e);
e.printStackTrace();
}
return config;
}
}
@@ -1,47 +0,0 @@
package com.jero.boot.starter.lock.core.strategy.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.jero.boot.starter.lock.core.strategy.RedissonConfigStrategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import com.jero.boot.starter.lock.enums.GlobalConstant;
import org.redisson.config.Config;
/**
* 哨兵方式Redis连接配置
* 比如sentinel.conf里配置为sentinel monitor my-sentinel-name 127.0.0.1 6379 2,那么这里就配置my-sentinel-name
* 配置方式:my-sentinel-name,127.0.0.1:26379,127.0.0.1:26389,127.0.0.1:26399
* @author zyf
* @date 2020-11-11
*/
@Slf4j
public class SentinelRedissonConfigStrategyImpl implements RedissonConfigStrategy {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
int database = redissonProperties.getDatabase();
String[] addrTokens = address.split(",");
String sentinelAliasName = addrTokens[0];
// 设置redis配置文件sentinel.conf配置的sentinel别名
config.useSentinelServers().setMasterName(sentinelAliasName);
config.useSentinelServers().setDatabase(database);
if (StringUtils.isNotBlank(password)) {
config.useSentinelServers().setPassword(password);
}
// 设置哨兵节点的服务IP和端口
for (int i = 1; i < addrTokens.length; i++) {
config.useSentinelServers().addSentinelAddress(GlobalConstant.REDIS_CONNECTION_PREFIX+ addrTokens[i]);
}
log.info("初始化哨兵方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("哨兵Redisson初始化错误", e);
e.printStackTrace();
}
return config;
}
}
@@ -1,40 +0,0 @@
package com.jero.boot.starter.lock.core.strategy.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.jero.boot.starter.lock.core.strategy.RedissonConfigStrategy;
import com.jero.boot.starter.lock.prop.RedissonProperties;
import com.jero.boot.starter.lock.enums.GlobalConstant;
import org.redisson.config.Config;
/**
* 单机方式Redisson配置
*
* @author zyf
* @date 2020-11-11
*/
@Slf4j
public class StandaloneRedissonConfigStrategyImpl implements RedissonConfigStrategy {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
int database = redissonProperties.getDatabase();
String redisAddr = GlobalConstant.REDIS_CONNECTION_PREFIX + address;
config.useSingleServer().setAddress(redisAddr);
config.useSingleServer().setDatabase(database);
if (StringUtils.isNotBlank(password)) {
config.useSingleServer().setPassword(password);
}
log.info("初始化Redisson单机配置,连接地址:" + address);
} catch (Exception e) {
log.error("单机Redisson初始化错误", e);
e.printStackTrace();
}
return config;
}
}
@@ -1,21 +0,0 @@
package com.jero.boot.starter.lock.enums;
/**
* 全局常量枚举
*
* @author zyf
* @date 2020-11-11
*/
public class GlobalConstant {
private GlobalConstant(){
}
/**
* Redis地址连接前缀
*/
public static final String REDIS_CONNECTION_PREFIX = "redis://";
}
@@ -1,22 +0,0 @@
package com.jero.boot.starter.lock.enums;
/**
* 锁的模式
* @author jero
*/
public enum LockModel {
//可重入锁
REENTRANT,
//公平锁
FAIR,
//联锁(可以把一组锁当作一个锁来加锁和释放)
MULTIPLE,
//红锁
REDLOCK,
//读锁
READ,
//写锁
WRITE,
//自动模式,当参数只有一个.使用 REENTRANT 参数多个 REDLOCK
AUTO
}
@@ -1,39 +0,0 @@
package com.jero.boot.starter.lock.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Redis连接方式
* @author zyf
* @date 2020-11-11
*/
@Getter
@AllArgsConstructor
public enum RedisConnectionType {
/**
* 单机部署方式(默认)
*/
STANDALONE("standalone", "单机部署方式"),
/**
* 哨兵部署方式
*/
SENTINEL("sentinel", "哨兵部署方式"),
/**
* 集群部署方式
*/
CLUSTER("cluster", "集群方式"),
/**
* 主从部署方式
*/
MASTERSLAVE("masterslave", "主从部署方式");
/**
* 编码
*/
private final String code;
/**
* 名称
*/
private final String name;
}
@@ -1,39 +0,0 @@
package com.jero.boot.starter.lock.prop;
import lombok.Data;
import com.jero.boot.starter.lock.enums.RedisConnectionType;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Redisson配置映射类
*
* @author zyf
* @date 2020-11-11
*/
@Data
@ConfigurationProperties(prefix = "jero.redisson")
public class RedissonProperties {
/**
* redis主机地址,ipport,多个用逗号(,)分隔
*/
private String address;
/**
* 连接类型
*/
private RedisConnectionType type;
/**
* 密码
*/
private String password;
/**
* 数据库(默认0)
*/
private int database;
/**
* 是否装配redisson配置
*/
private Boolean enabled = true;
}
@@ -1,4 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.jero.boot.starter.lock.config.RedissonConfiguration
@@ -1,59 +0,0 @@
package org.jero.boot.starter.lock.test;
import com.jero.boot.starter.lock.annotation.JLock;
import com.jero.boot.starter.lock.annotation.JRepeat;
import com.jero.boot.starter.lock.annotation.LockConstant;
import com.jero.boot.starter.lock.client.RedissonLockClient;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class LockService {
@Resource
private RedissonLockClient redissonLockClient;
int n = 10;
/**
* 模拟秒杀(注解方式)
*/
@JLock(lockKey = "#productId", expireSeconds = 5000)
public void seckill(String productId) {
if (n <= 0) {
System.out.println("活动已结束,请下次再来");
return;
}
System.out.println(Thread.currentThread().getName() + ":秒杀到了商品");
System.out.println(--n);
}
/**
* 模拟秒杀(编程方式)
*/
public void seckill2(String productId) {
redissonLockClient.tryLock(productId, 5000);
if (n <= 0) {
System.out.println("活动已结束,请下次再来");
return;
}
System.out.println(Thread.currentThread().getName() + ":秒杀到了商品");
System.out.println(--n);
redissonLockClient.unlock(productId);
}
/**
* 测试重复提交
*/
@JRepeat(lockKey = "#name", lockTime = 5)
public void reSubmit(String name) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("提交成功" + name);
}
}
@@ -1,69 +0,0 @@
package org.jero.boot.starter.lock.test;
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.test.context.junit4.SpringRunner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import static junit.framework.TestCase.assertNull;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LockTestApplication.class)
public class LockTest {
@Autowired
LockService lockService;
/**
* 测试分布式锁(模拟秒杀)
*/
@Test
public void test1() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(6);
IntStream.range(0, 30).forEach(i -> executorService.submit(() -> {
try {
lockService.seckill("20120508784");
} catch (Exception e) {
e.printStackTrace();
}
}));
assertNull(executorService.awaitTermination(30, TimeUnit.SECONDS));
}
/**
* 测试分布式锁(模拟秒杀)
*/
@Test
public void test2() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(6);
IntStream.range(0, 30).forEach(i -> executorService.submit(() -> {
try {
lockService.seckill2("20120508784");
} catch (Exception e) {
e.printStackTrace();
}
}));
assertNull(executorService.awaitTermination(30, TimeUnit.SECONDS));
}
/**
* 测试分布式锁(模拟重复提交)
*/
@Test
public void test3() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(6);
IntStream.range(0, 20).forEach(i -> executorService.submit(() -> {
try {
lockService.reSubmit("test");
} catch (Exception e) {
e.printStackTrace();
}
}));
assertNull(executorService.awaitTermination(30, TimeUnit.SECONDS));
}
}
@@ -1,15 +0,0 @@
package org.jero.boot.starter.lock.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication(scanBasePackages = "com.jero")
@EnableAspectJAutoProxy
public class LockTestApplication {
public static void main(String[] args) {
SpringApplication.run(LockTestApplication.class, args);
}
}
@@ -1,9 +0,0 @@
package org.jero.boot.starter.lock.test;
import lombok.Data;
@Data
public class TestUser {
private String userId;
private String userName;
}
@@ -1,19 +0,0 @@
spring:
redis:
database: 0
host: 127.0.0.1
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: hzwlsoft123
port: 6379
jero :
redisson:
address: 127.0.0.1:6379
password: hzwlsoft123
type: STANDALONE
enabled: true
@@ -1,21 +0,0 @@
<?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>jero-boot-starter</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-boot-starter-rabbitmq</artifactId>
<description>jero-boot-starter-消息队列</description>
<dependencies>
<!-- 消息总线 rabbitmq -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,364 +0,0 @@
package com.jero.boot.starter.rabbitmq.client;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import com.jero.boot.starter.rabbitmq.event.EventObj;
import com.jero.boot.starter.rabbitmq.event.JeroRemoteApplicationEvent;
import com.jero.boot.starter.rabbitmq.exchange.DelayExchangeBuilder;
import com.jero.common.annotation.RabbitComponent;
import com.jero.common.base.BaseMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 消息队列客户端
*/
@Slf4j
@Configuration
public class RabbitMqClient {
private final RabbitAdmin rabbitAdmin;
private final RabbitTemplate rabbitTemplate;
@Resource
private SimpleMessageListenerContainer messageListenerContainer;
@Resource
BusProperties busProperties;
@Resource
private ApplicationEventPublisher publisher;
@Resource
private ApplicationContext applicationContext;
@Bean
public void initQueue() {
Map<String, Object> beansWithRqbbitComponentMap = this.applicationContext.getBeansWithAnnotation(RabbitComponent.class);
Class<? extends Object> clazz = null;
for (Map.Entry<String, Object> entry : beansWithRqbbitComponentMap.entrySet()) {
log.info("初始化队列............");
//获取到实例对象的class信息
clazz = entry.getValue().getClass();
Method[] methods = clazz.getMethods();
RabbitListener rabbitListener = clazz.getAnnotation(RabbitListener.class);
if (ObjectUtil.isNotEmpty(rabbitListener)) {
createQueue(rabbitListener);
}
for (Method method : methods) {
RabbitListener methodRabbitListener = method.getAnnotation(RabbitListener.class);
if (ObjectUtil.isNotEmpty(methodRabbitListener)) {
createQueue(methodRabbitListener);
}
}
}
}
/**
* 初始化队列
*
* @param rabbitListener
*/
private void createQueue(RabbitListener rabbitListener) {
String[] queues = rabbitListener.queues();
DirectExchange directExchange = createExchange(DelayExchangeBuilder.DELAY_EXCHANGE);
//创建交换机
rabbitAdmin.declareExchange(directExchange);
if (ObjectUtil.isNotEmpty(queues)) {
for (String queueName : queues) {
Properties result = rabbitAdmin.getQueueProperties(queueName);
if (ObjectUtil.isEmpty(result)) {
Queue queue = new Queue(queueName);
addQueue(queue);
Binding binding = BindingBuilder.bind(queue).to(directExchange).with(queueName);
rabbitAdmin.declareBinding(binding);
log.info("创建队列:" + queueName);
}else{
log.info("已有队列:" + queueName);
}
}
}
}
private Map<String,Object> sentObj = new HashMap<>();
@Autowired
public RabbitMqClient(RabbitAdmin rabbitAdmin, RabbitTemplate rabbitTemplate) {
this.rabbitAdmin = rabbitAdmin;
this.rabbitTemplate = rabbitTemplate;
}
/**
* 发送远程事件
*
* @param handlerName
* @param baseMap
*/
public void publishEvent(String handlerName, BaseMap baseMap) {
EventObj eventObj = new EventObj();
eventObj.setHandlerName(handlerName);
eventObj.setBaseMap(baseMap);
publisher.publishEvent(new JeroRemoteApplicationEvent(eventObj, busProperties.getId()));
}
/**
* 转换Message对象
*
* @param messageType 返回消息类型 MessageProperties类中常量
* @param msg
* @return
*/
public Message getMessage(String messageType, Object msg) {
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType(messageType);
return new Message(msg.toString().getBytes(), messageProperties);
}
/**
* 有绑定Key的Exchange发送
*
* @param routingKey
* @param msg
*/
public void sendMessageToExchange(TopicExchange topicExchange, String routingKey, Object msg) {
Message message = getMessage(MessageProperties.CONTENT_TYPE_JSON, msg);
rabbitTemplate.send(topicExchange.getName(), routingKey, message);
}
/**
* 没有绑定KEY的Exchange发送
*
* @param exchange
* @param msg
*/
public void sendMessageToExchange(TopicExchange topicExchange, AbstractExchange exchange, String msg) {
addExchange(exchange);
log.info("RabbitMQ send " + exchange.getName() + "->" + msg);
rabbitTemplate.convertAndSend(topicExchange.getName(), msg);
}
/**
* 发送消息
*
* @param queueName 队列名称
* @param params 消息内容map
*/
public void sendMessage(String queueName, Object params) {
log.info("发送消息到mq");
try {
rabbitTemplate.convertAndSend(DelayExchangeBuilder.DELAY_EXCHANGE, queueName, params, message -> message);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送消息
*
* @param queueName 队列名称
*/
public void sendMessage(String queueName) {
this.send(queueName, this.sentObj, 0);
this.sentObj.clear();
}
public RabbitMqClient put(String key, Object value) {
this.sentObj.put(key, value);
return this;
}
/**
* 延迟发送消息
*
* @param queueName 队列名称
* @param params 消息内容params
* @param expiration 延迟时间 单位毫秒
*/
public void sendMessage(String queueName, Object params, Integer expiration) {
this.send(queueName, params, expiration);
}
private void send(String queueName, Object params, Integer expiration) {
Queue queue = new Queue(queueName);
addQueue(queue);
CustomExchange customExchange = DelayExchangeBuilder.buildExchange();
rabbitAdmin.declareExchange(customExchange);
Binding binding = BindingBuilder.bind(queue).to(customExchange).with(queueName).noargs();
rabbitAdmin.declareBinding(binding);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.debug("发送时间:" + sf.format(new Date()));
messageListenerContainer.setQueueNames(queueName);
/* messageListenerContainer.setMessageListener(new MqListener<Message>() {
@Override
public void onMessage(Message message, Channel channel) {
MqListener messageListener = SpringContextHolder.getHandler(queueName + "Listener", MqListener.class);
if (ObjectUtil.isNotEmpty(messageListener)) {
messageListener.onMessage(message, channel);
}
}
});*/
rabbitTemplate.convertAndSend(DelayExchangeBuilder.DEFAULT_DELAY_EXCHANGE, queueName, params, message -> {
if (expiration != null && expiration > 0) {
message.getMessageProperties().setHeader("x-delay", expiration);
}
return message;
});
}
/**
* 给queue发送消息
*
* @param queueName
*/
public String receiveFromQueue(String queueName) {
return receiveFromQueue(DirectExchange.DEFAULT, queueName);
}
/**
* 给direct交换机指定queue发送消息
*
* @param directExchange
* @param queueName
*/
public String receiveFromQueue(DirectExchange directExchange, String queueName) {
Queue queue = new Queue(queueName);
addQueue(queue);
Binding binding = BindingBuilder.bind(queue).to(directExchange).withQueueName();
rabbitAdmin.declareBinding(binding);
String messages = (String) rabbitTemplate.receiveAndConvert(queueName);
log.info("Receive:" + messages);
return messages;
}
/**
* 创建Exchange
*
* @param exchange
*/
public void addExchange(AbstractExchange exchange) {
rabbitAdmin.declareExchange(exchange);
}
/**
* 删除一个Exchange
*
* @param exchangeName
*/
public boolean deleteExchange(String exchangeName) {
return rabbitAdmin.deleteExchange(exchangeName);
}
/**
* 声明其名称自动命名的队列。它是用exclusive=true、autoDelete=true和 durable = false
*
* @return Queue
*/
public Queue addQueue() {
return rabbitAdmin.declareQueue();
}
/**
* 创建一个指定的Queue
*
* @param queue
* @return queueName
*/
public String addQueue(Queue queue) {
return rabbitAdmin.declareQueue(queue);
}
/**
* 删除一个队列
*
* @param queueName the name of the queue.
* @param unused true if the queue should be deleted only if not in use.
* @param empty true if the queue should be deleted only if empty.
*/
public void deleteQueue(String queueName, boolean unused, boolean empty) {
rabbitAdmin.deleteQueue(queueName, unused, empty);
}
/**
* 删除一个队列
*
* @param queueName
* @return true if the queue existed and was deleted.
*/
public boolean deleteQueue(String queueName) {
return rabbitAdmin.deleteQueue(queueName);
}
/**
* 绑定一个队列到一个匹配型交换器使用一个routingKey
*
* @param queue
* @param exchange
* @param routingKey
*/
public void addBinding(Queue queue, TopicExchange exchange, String routingKey) {
Binding binding = BindingBuilder.bind(queue).to(exchange).with(routingKey);
rabbitAdmin.declareBinding(binding);
}
/**
* 绑定一个Exchange到一个匹配型Exchange 使用一个routingKey
*
* @param exchange
* @param topicExchange
* @param routingKey
*/
public void addBinding(Exchange exchange, TopicExchange topicExchange, String routingKey) {
Binding binding = BindingBuilder.bind(exchange).to(topicExchange).with(routingKey);
rabbitAdmin.declareBinding(binding);
}
/**
* 去掉一个binding
*
* @param binding
*/
public void removeBinding(Binding binding) {
rabbitAdmin.removeBinding(binding);
}
/**
* 创建交换器
*
* @param exchangeName
* @return
*/
public DirectExchange createExchange(String exchangeName) {
return new DirectExchange(exchangeName, true, false);
}
}
@@ -1,66 +0,0 @@
package com.jero.boot.starter.rabbitmq.config;
import com.jero.boot.starter.rabbitmq.event.JeroRemoteApplicationEvent;
import com.jero.common.config.mqtoken.TransmitUserTokenFilter;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.UUID;
/**
* 消息队列配置类
*
* @author zyf
*/
@Configuration
@RemoteApplicationEventScan(basePackageClasses = JeroRemoteApplicationEvent.class)
public class RabbitMqConfig {
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
//设置忽略声明异常
rabbitAdmin.setIgnoreDeclarationExceptions(true);
return rabbitAdmin;
}
/**
* 注入获取token过滤器
* @return
*/
@Bean
public TransmitUserTokenFilter transmitUserInfoFromHttpHeader(){
return new TransmitUserTokenFilter();
}
@Bean
public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//手动确认
container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//当前的消费者数量
container.setConcurrentConsumers(1);
//最大的消费者数量
container.setMaxConcurrentConsumers(1);
//是否重回队列
container.setDefaultRequeueRejected(true);
//消费端的标签策略
/*container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue + "_" + UUID.randomUUID().toString();
}
});*/
container.setConsumerTagStrategy(queue-> queue + "_" + UUID.randomUUID());
return container;
}
}
@@ -1,35 +0,0 @@
package com.jero.boot.starter.rabbitmq.core;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import com.jero.boot.starter.rabbitmq.listenter.MqListener;
import com.jero.common.config.mqtoken.UserTokenContext;
import java.io.IOException;
@Slf4j
public class BaseRabbiMqHandler<T> {
private String token= UserTokenContext.getToken();
public void onMessage(T t, Long deliveryTag, Channel channel, MqListener<T> mqListener) {
try {
UserTokenContext.setToken(token);
mqListener.handler(t, channel);
channel.basicAck(deliveryTag, false);
} catch (Exception e) {
log.info("接收消息失败,重新放回队列");
try {
/**
* deliveryTag:该消息的index
* multiple:是否批量.true:将一次性拒绝所有小于deliveryTag的消息。
* requeue:被拒绝的是否重新入队列
*/
channel.basicNack(deliveryTag, false, true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
@@ -1,36 +0,0 @@
package com.jero.boot.starter.rabbitmq.core;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
public class MapMessageConverter implements MessageConverter {
@Override
public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
return new Message(object.toString().getBytes(), messageProperties);
}
@Override
public Object fromMessage(Message message) throws MessageConversionException {
String contentType = message.getMessageProperties().getContentType();
if (null != contentType && contentType.contains("text")) {
return new String(message.getBody());
} else {
ObjectInputStream objInt = null;
try {
ByteArrayInputStream byteInt = new ByteArrayInputStream(message.getBody());
objInt = new ObjectInputStream(byteInt);
//byte[]转map
return objInt.readObject();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
@@ -1,28 +0,0 @@
package com.jero.boot.starter.rabbitmq.event;
import cn.hutool.core.util.ObjectUtil;
import com.jero.common.util.SpringContextHolder;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 监听远程事件,并分发消息到业务模块消息处理器
*/
@Component
public class BaseApplicationEvent implements ApplicationListener<JeroRemoteApplicationEvent> {
@Override
public void onApplicationEvent(JeroRemoteApplicationEvent jeroRemoteApplicationEvent) {
EventObj eventObj = jeroRemoteApplicationEvent.getEventObj();
if (ObjectUtil.isNotEmpty(eventObj)) {
//获取业务模块消息处理器
JeroBusEventHandler busEventHandler = SpringContextHolder.getHandler(eventObj.getHandlerName(), JeroBusEventHandler.class);
if (ObjectUtil.isNotEmpty(busEventHandler)) {
//通知业务模块
busEventHandler.onMessage(eventObj);
}
}
}
}
@@ -1,21 +0,0 @@
package com.jero.boot.starter.rabbitmq.event;
import lombok.Data;
import com.jero.common.base.BaseMap;
import java.io.Serializable;
/**
* 远程事件数据对象
*/
@Data
public class EventObj implements Serializable {
/**
* 数据对象
*/
private BaseMap baseMap;
/**
* 自定义业务模块消息处理器beanName
*/
private String handlerName;
}
@@ -1,8 +0,0 @@
package com.jero.boot.starter.rabbitmq.event;
/**
* 业务模块消息处理器接口
*/
public interface JeroBusEventHandler {
void onMessage(EventObj map);
}
@@ -1,29 +0,0 @@
package com.jero.boot.starter.rabbitmq.event;
import lombok.Data;
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
/**
* 自定义网关刷新远程事件
*
* @author : zyf
* @date :2020-11-10
*/
@Data
public class JeroRemoteApplicationEvent extends RemoteApplicationEvent {
private JeroRemoteApplicationEvent() {
}
private EventObj eventObj;
public JeroRemoteApplicationEvent(EventObj source, String originService, String destinationService) {
super(source, originService, destinationService);
this.eventObj = source;
}
public JeroRemoteApplicationEvent(EventObj source, String originService) {
super(source, originService, null);
this.eventObj = source;
}
}
@@ -1,36 +0,0 @@
package com.jero.boot.starter.rabbitmq.exchange;
import org.springframework.amqp.core.CustomExchange;
import java.util.HashMap;
import java.util.Map;
/**
* 延迟交换器构造器
* @author: zyf
* @date: 2019/3/8 13:31
* @description:
*/
public class DelayExchangeBuilder {
/**
* 默认延迟消息交换器
*/
public static final String DEFAULT_DELAY_EXCHANGE = "jero.delayed.exchange";
/**
* 普通交换器
*/
public static final String DELAY_EXCHANGE = "jero.direct.exchange";
private DelayExchangeBuilder() {
}
/**
* 构建延迟消息交换器
* @return
*/
public static CustomExchange buildExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange(DEFAULT_DELAY_EXCHANGE, "x-delayed-message", true, false, args);
}
}
@@ -1,10 +0,0 @@
package com.jero.boot.starter.rabbitmq.listenter;
import com.rabbitmq.client.Channel;
public interface MqListener<T> {
default void handler(T map, Channel channel) {
}
}
-41
View File
@@ -1,41 +0,0 @@
<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>
<groupId>com.jero.boot</groupId>
<artifactId>jero-boot</artifactId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-boot-starter</artifactId>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>jero-boot-starter-cloud</module>
<module>jero-boot-starter-job</module>
<module>jero-boot-starter-lock</module>
<module>jero-boot-starter-rabbitmq</module>
</modules>
<dependencies>
<!--jero-tools-->
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>jero-boot-base-tools</artifactId>
</dependency>
<!--加载配置信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
-92
View File
@@ -1,92 +0,0 @@
version: '2'
services:
jero-boot-mysql:
build:
context: ../db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
TZ: Asia/Shanghai
restart: always
container_name: jero-boot-mysql
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
--default-authentication-plugin=caching_sha2_password
ports:
- 3306:3306
jero-boot-redis:
image: redis:5.0
ports:
- 6379:6379
restart: always
container_name: jero-boot-redis
hostname: jero-boot-redis
jero-boot-nacos:
restart: always
image: nacos/nacos-server:1.4.0
container_name: jero-boot-nacos
hostname: jero-boot-nacos
ports:
- 8848:8848
depends_on:
- jero-boot-mysql
# volumes:
# - ./init/docker-startup.sh:/home/nacos/bin/docker-startup.sh
# - ./init/application.properties:/home/nacos/conf/application.properties
environment:
MODE: standalone
PREFER_HOST_MODE: hostname
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: jero-boot-mysql
MYSQL_SERVICE_PORT: 3306
MYSQL_SERVICE_USER: root
MYSQL_SERVICE_PASSWORD: root
MYSQL_SERVICE_DB_NAME: nacos
jero-boot-gateway:
build:
context: ./jero-cloud-gateway
ports:
- 9999:9999
depends_on:
- jero-boot-nacos
- jero-boot-redis
container_name: jero-boot-gateway
hostname: jero-boot-gateway
jero-boot-system:
depends_on:
- jero-boot-mysql
- jero-boot-redis
- jero-boot-nacos
build:
context: ./jero-cloud-system-start
container_name: jero-boot-system
hostname: jero-boot-system
restart: on-failure
environment:
- TZ=Asia/Shanghai
jero-boot-xxljob:
build:
context: ./jero-cloud-xxljob
ports:
- 9080:9080
container_name: jero-boot-xxljob
hostname: jero-boot-xxljob
# jero-boot-rabbitmq:
# # image: rabbitmq:3-management
# image: rabbitmq:3
# ports:
# - 5672:5672
# # - 15672:15672
# restart: always
# container_name: jero-boot-rabbitmq
# hostname: jero-boot-rabbitmq
@@ -1,15 +0,0 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER test@163.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /jero-cloud-gateway
WORKDIR /jero-cloud-gateway
EXPOSE 9999
ADD ./target/jero-cloud-gateway-2.5.0.jar ./
CMD java -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -jar jero-cloud-gateway-2.5.0.jar
@@ -1,105 +0,0 @@
<?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>jero-cloud-module</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-cloud-gateway</artifactId>
<dependencies>
<!-- jero 微服务基础依赖-->
<dependency>
<groupId>com.jero.boot</groupId>
<artifactId>jero-boot-starter-cloud</artifactId>
<exclusions>
<exclusion>
<groupId>com.jero.boot</groupId>
<artifactId>jero-system-cloud-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-cloud网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--sentinel断路器依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
</dependency>
<!--Spring Webflux-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- 熔断、降级 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--健康监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 限流Redis实现 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!--springboot2.X默认使用lettuce连接池,需要引入commons-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!--server-api-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- Swagger API文档 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-ui</artifactId>
<version>${knife4j-spring-ui.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j-spring-boot-starter.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
@@ -1,34 +0,0 @@
package com.jero;
import com.jero.loader.DynamicRouteLoader;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import javax.annotation.Resource;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class JeroGatewayApplication implements CommandLineRunner {
@Resource
private DynamicRouteLoader dynamicRouteLoader;
public static void main(String[] args) {
SpringApplication.run(JeroGatewayApplication.class, args);
}
/**
* 容器初始化后加载路由
* @param strings
*/
@Override
public void run(String... strings) {
dynamicRouteLoader.refresh();
}
}
@@ -1,110 +0,0 @@
package com.jero.config;
import lombok.extern.slf4j.Slf4j;
import com.jero.handler.HystrixFallbackHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import javax.annotation.Resource;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
/**
* @author scott
* @date 2020/05/26
* 路由配置信息
*/
@Slf4j
@Configuration
public class GatewayRoutersConfiguration {
public static final long DEFAULT_TIMEOUT = 30000;
public static String SERVER_ADDR;
public static String NAMESPACE;
public static String DATA_ID;
public static String ROUTE_GROUP;
/**
* 路由配置文件数据获取方式yml,nacos,database
*/
public static String DATA_TYPE;
@Value("${spring.cloud.nacos.discovery.server-addr}")
public void setServerAddr(String serverAddr) {
synchronized (GatewayRoutersConfiguration.class){
if(SERVER_ADDR == null){
SERVER_ADDR = serverAddr;
}
}
}
@Value("${spring.cloud.nacos.discovery.namespace}")
public void setNamespace(String namespace) {
synchronized (GatewayRoutersConfiguration.class){
if(NAMESPACE == null){
NAMESPACE = namespace;
}
}
}
@Value("${jero.route.config.data-id:#{null}}")
public void setRouteDataId(String dataId) {
synchronized (GatewayRoutersConfiguration.class){
if(DATA_ID == null){
DATA_ID = dataId + ".json";
}
}
}
@Value("${jero.route.config.group:DEFAULT_GROUP:#{null}}")
public void setRouteGroup(String routeGroup) {
synchronized (GatewayRoutersConfiguration.class){
if(ROUTE_GROUP == null){
ROUTE_GROUP = routeGroup;
}
}
}
@Value("${jero.route.config.data-type}")
public void setDataType(String dataType) {
synchronized (GatewayRoutersConfiguration.class){
if(DATA_TYPE == null){
DATA_TYPE = dataType;
}
}
}
/**
* 路由断言
* @return
*/
@Bean
public RouterFunction<ServerResponse> routerFunction() {
return RouterFunctions.route(
RequestPredicates.path("/globalFallback").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler);
}
@Bean
public RouterFunction<ServerResponse> indexRouter(@Value("classpath:/META-INF/resources/doc.html") final org.springframework.core.io.Resource indexHtml) {
return route(GET("/"), request -> ok().contentType(MediaType.TEXT_HTML).syncBody(indexHtml));
}
@Resource
private HystrixFallbackHandler hystrixFallbackHandler;
}
@@ -1,43 +0,0 @@
package com.jero.config;
import com.jero.filter.GlobalAccessTokenFilter;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import reactor.core.publisher.Mono;
/**
* @author scott
* @date 2020/5/26
* 路由限流配置
*/
@Configuration
public class RateLimiterConfiguration {
/**
* IP限流 (通过exchange对象可以获取到请求信息,这边用了HostName)
*/
@Bean
@Primary
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
/**
* 用户限流 (通过exchange对象可以获取到请求信息,获取当前请求的用户 TOKEN)
*/
@Bean
public KeyResolver userKeyResolver() {
//使用这种方式限流,请求Header中必须携带X-Access-Token参数
return exchange -> Mono.just(exchange.getRequest().getHeaders().getFirst(GlobalAccessTokenFilter.X_ACCESS_TOKEN));
}
/**
* 接口限流 (获取请求地址的uri作为限流key)
*/
@Bean
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
}
@@ -1,22 +0,0 @@
package com.jero.config;
/**
* nocos配置方式枚举
*/
public class RouterDataType {
private RouterDataType(){
}
/**
* 数据库加载路由配置
*/
public static final String DATABASE = "database";
/**
* 本地yml加载路由配置
*/
public static final String YML = "yml";
/**
* nacos加载路由配置
*/
public static final String NACOS = "nacos";
}
@@ -1,32 +0,0 @@
package com.jero.fallback;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
/**
* 响应超时熔断处理器
*
* @author zyf
*/
@RestController
public class FallbackController {
/**
* 全局熔断处理
* @return
*/
@RequestMapping("/fallback")
public Mono<String> fallback() {
return Mono.just("访问超时,请稍后再试!");
}
/**
* demo熔断处理
* @return
*/
@RequestMapping("/demo/fallback")
public Mono<String> fallback2() {
return Mono.just("访问超时,请稍后再试!");
}
}
@@ -1,54 +0,0 @@
package com.jero.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.io.File;
import java.util.Arrays;
import java.util.stream.Collectors;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
/**
*
*/
@Slf4j
@Component
public class GlobalAccessTokenFilter implements GlobalFilter, Ordered {
public static final String X_ACCESS_TOKEN = "X-Access-Token";
public static final String X_GATEWAY_BASE_PATH = "X_GATEWAY_BASE_PATH";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String scheme = exchange.getRequest().getURI().getScheme();
String host = exchange.getRequest().getURI().getHost();
int port = exchange.getRequest().getURI().getPort();
String basePath = scheme + "://" + host + ":" + port;
// 1. 重写StripPrefix(获取真实的URL)
addOriginalRequestUrl(exchange, exchange.getRequest().getURI());
String rawPath = exchange.getRequest().getURI().getRawPath();
String newPath = File.separator + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, File.separator)).skip(1L).collect(Collectors.joining("/"));
ServerHttpRequest newRequest = exchange.getRequest().mutate().path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
//将现在的request,添加当前身份
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserName", "").header(X_GATEWAY_BASE_PATH,basePath).build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
return chain.filter(mutableExchange);
}
@Override
public int getOrder() {
return 0;
}
}
@@ -1,26 +0,0 @@
package com.jero.filter;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
/**
* @author Administrator
*/
@Configuration
public class SentinelFilterContextConfig {
@Bean
public FilterRegistrationBean<Filter> sentinelFilterRegistration() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}
@@ -1,34 +0,0 @@
package com.jero.handler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.util.Optional;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR;
/**
* @author scott
* @date 2020/05/26
* Hystrix 降级处理
*/
@Slf4j
@Component
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse> {
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
Optional<Object> originalUris = serverRequest.attribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
originalUris.ifPresent(originalUri -> log.error("网关执行请求:{}失败,hystrix服务降级处理", originalUri));
return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
.header("Content-Type","text/plain; charset=utf-8").body(BodyInserters.fromObject("访问超时,请稍后再试"));
}
}
@@ -1,27 +0,0 @@
package com.jero.handler;
import com.jero.common.base.BaseMap;
import com.jero.common.modules.redis.listener.JeroRedisListerer;
import lombok.extern.slf4j.Slf4j;
import com.jero.loader.DynamicRouteLoader;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 路由刷新监听
*/
@Slf4j
@Component
public class LoderRouderHandler implements JeroRedisListerer {
@Resource
private DynamicRouteLoader dynamicRouteLoader;
@Override
public void onMessage(BaseMap message) {
dynamicRouteLoader.refresh();
}
}
@@ -1,67 +0,0 @@
package com.jero.handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.*;
/**
* 聚合各个服务的swagger接口
*/
@Component
@Primary
public class MySwaggerResourceProvider implements SwaggerResourcesProvider {
/**
* swagger2默认的url后缀
*/
private static final String SWAGGER2URL = "/v2/api-docs";
/**
* 网关路由
*/
private final RouteLocator routeLocator;
/**
* 网关应用名称
*/
@Value("${spring.application.name}")
private String self;
@Autowired
public MySwaggerResourceProvider(RouteLocator routeLocator) {
this.routeLocator = routeLocator;
}
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routeHosts = new ArrayList<>();
// 获取所有可用的hostserviceId
routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
.filter(route -> !self.equals(route.getUri().getHost()))
.subscribe(route -> routeHosts.add(route.getUri().getHost()));
// 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上
Set<String> dealed = new HashSet<>();
routeHosts.forEach(instance -> {
// 拼接url
String url = "/" + instance.toLowerCase() + SWAGGER2URL;
if (!dealed.contains(url)) {
dealed.add(url);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setUrl(url);
swaggerResource.setName(instance);
//Swagger排除监控
if(instance.indexOf("jero-cloud-monitor")==-1){
resources.add(swaggerResource);
}
}
});
return resources;
}
}
@@ -1,39 +0,0 @@
package com.jero.handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.swagger.web.*;
import java.util.List;
/**
* swagger聚合接口,三个接口都是 doc.html需要访问的接口
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerResourceController {
private MySwaggerResourceProvider swaggerResourceProvider;
@Autowired
public SwaggerResourceController(MySwaggerResourceProvider swaggerResourceProvider) {
this.swaggerResourceProvider = swaggerResourceProvider;
}
@RequestMapping(value = "/configuration/security")
public ResponseEntity<SecurityConfiguration> securityConfiguration() {
return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK);
}
@RequestMapping(value = "/configuration/ui")
public ResponseEntity<UiConfiguration> uiConfiguration() {
return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK);
}
@RequestMapping
public ResponseEntity<List<SwaggerResource>> swaggerResources() {
return new ResponseEntity<>(swaggerResourceProvider.get(), HttpStatus.OK);
}
}
@@ -1,290 +0,0 @@
package com.jero.loader;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.google.common.collect.Lists;
import com.jero.common.constant.CacheConstant;
import com.jero.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import com.jero.config.GatewayRoutersConfiguration;
import com.jero.config.RouterDataType;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;
/**
* 动态路由加载器
*
* @author : zyf
* @date :2020-11-10
*/
@Slf4j
@Component
@DependsOn({"gatewayRoutersConfiguration"})
public class DynamicRouteLoader implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
private InMemoryRouteDefinitionRepository repository;
private DynamicRouteService dynamicRouteService;
private ConfigService configService;
private RedisUtil redisUtil;
private static String updateRouteText = "update route : {}";
public DynamicRouteLoader(InMemoryRouteDefinitionRepository repository, DynamicRouteService dynamicRouteService, RedisUtil redisUtil) {
if(this.repository == null){
this.repository = repository;
}
this.dynamicRouteService = dynamicRouteService;
this.redisUtil = redisUtil;
}
@PostConstruct
public void init() {
String dataType = GatewayRoutersConfiguration.DATA_TYPE;
log.info("初始化路由,dataType"+ dataType);
if (RouterDataType.NACOS.endsWith(dataType)) {
loadRoutesByNacos();
}
//从数据库加载路由
if (RouterDataType.DATABASE.endsWith(dataType)) {
loadRoutesByRedis();
}
}
/**
* 刷新路由
*
* @return
*/
public Mono<Void> refresh() {
String dataType = GatewayRoutersConfiguration.DATA_TYPE;
if (!RouterDataType.YML.endsWith(dataType)) {
this.init();
}
return Mono.empty();
}
/**
* 从nacos中读取路由配置
*
* @return
*/
private void loadRoutesByNacos() {
List<RouteDefinition> routes = Lists.newArrayList();
configService = createConfigService();
try {
String configInfo = "";
if (configService == null) {
log.warn("initConfigService fail");
}else {
configInfo = configService.getConfig(GatewayRoutersConfiguration.DATA_ID, GatewayRoutersConfiguration.ROUTE_GROUP, GatewayRoutersConfiguration.DEFAULT_TIMEOUT);
}
if (StringUtils.isNotBlank(configInfo)) {
log.info("获取网关当前配置:\r\n{}", configInfo);
routes = JSON.parseArray(configInfo, RouteDefinition.class);
}
} catch (NacosException e) {
log.error("初始化网关路由时发生错误", e);
e.printStackTrace();
}
for (RouteDefinition definition : routes) {
log.info(updateRouteText, definition.toString());
dynamicRouteService.add(definition);
}
this.publisher.publishEvent(new RefreshRoutesEvent(this));
dynamicRouteByNacosListener(GatewayRoutersConfiguration.DATA_ID, GatewayRoutersConfiguration.ROUTE_GROUP);
}
/**
* 从redis中读取路由配置
*
* @return
*/
private void loadRoutesByRedis() {
List<MyRouteDefinition> routes = Lists.newArrayList();
configService = createConfigService();
if (configService == null) {
log.warn("initConfigService fail");
}
Object configInfo = redisUtil.get(CacheConstant.GATEWAY_ROUTES);
if (ObjectUtil.isNotEmpty(configInfo)) {
log.info("获取网关当前配置:\r\n{}", configInfo);
JSONArray array = JSON.parseArray(configInfo.toString());
try {
routes = getRoutesByJson(array);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
for (MyRouteDefinition definition : routes) {
log.info(updateRouteText, definition.toString());
Integer status=definition.getStatus();
if(status.equals(0)){
dynamicRouteService.delete(definition.getId());
}else{
dynamicRouteService.add(definition);
}
}
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}
/**
* redis中的信息需要处理下 转成RouteDefinition对象
* - id: login
* uri: lb://cloud-jero-system
* predicates:
* - Path=/jero-boot/sys/**,
*
* @param array
* @return
*/
public static List<MyRouteDefinition> getRoutesByJson(JSONArray array) throws URISyntaxException {
List<MyRouteDefinition> ls = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
JSONObject obj = array.getJSONObject(i);
MyRouteDefinition route = new MyRouteDefinition();
route.setId(obj.getString("routerId"));
route.setStatus(obj.getInteger("status"));
Object uri = obj.get("uri");
if (uri == null) {
route.setUri(new URI("lb://" + obj.getString("name")));
} else {
route.setUri(new URI(obj.getString("uri")));
}
Object predicates = obj.get("predicates");
if (predicates != null) {
JSONArray list = JSON.parseArray(predicates.toString());
List<PredicateDefinition> predicateDefinitionList = getPredicateDefinitions(list);
route.setPredicates(predicateDefinitionList);
}
Object filters = obj.get("filters");
if (filters != null) {
JSONArray list = JSON.parseArray(filters.toString());
List<FilterDefinition> filterDefinitionList = new ArrayList<>();
if (ObjectUtil.isNotEmpty(list)) {
addFilterDefinition(list, filterDefinitionList);
route.setFilters(filterDefinitionList);
}
}
ls.add(route);
}
return ls;
}
private static void addFilterDefinition(JSONArray list, List<FilterDefinition> filterDefinitionList) {
for (Object map : list) {
JSONObject json = (JSONObject) map;
JSONArray jsonArray = json.getJSONArray("args");
String name = json.getString("name");
FilterDefinition filterDefinition = new FilterDefinition();
for (Object o : jsonArray) {
JSONObject params = (JSONObject) o;
filterDefinition.addArg(params.getString("key"), params.get("value").toString());
}
filterDefinition.setName(name);
filterDefinitionList.add(filterDefinition);
}
}
private static List<PredicateDefinition> getPredicateDefinitions(JSONArray list) {
List<PredicateDefinition> predicateDefinitionList = new ArrayList<>();
for (Object map : list) {
JSONObject json = (JSONObject) map;
PredicateDefinition predicateDefinition = new PredicateDefinition();
predicateDefinition.setName(json.getString("name"));
JSONArray jsonArray = json.getJSONArray("args");
for (int j = 0; j < jsonArray.size(); j++) {
predicateDefinition.addArg("_genkey" + j, jsonArray.get(j).toString());
}
predicateDefinitionList.add(predicateDefinition);
}
return predicateDefinitionList;
}
/**
* 监听Nacos下发的动态路由配置
*
* @param dataId
* @param group
*/
public void dynamicRouteByNacosListener(String dataId, String group) {
try {
configService.addListener(dataId, group, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
log.info("进行网关更新:\n\r{}", configInfo);
List<RouteDefinition> definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
for (RouteDefinition definition : definitionList) {
log.info(updateRouteText, definition.toString());
dynamicRouteService.update(definition);
}
}
@Override
public Executor getExecutor() {
log.info("getExecutor\n\r");
return null;
}
});
} catch (Exception e) {
log.error("从nacos接收动态路由配置出错!!!", e);
}
}
/**
* 创建ConfigService
*
* @return
*/
private ConfigService createConfigService() {
try {
Properties properties = new Properties();
properties.setProperty("serverAddr", GatewayRoutersConfiguration.SERVER_ADDR);
properties.setProperty("namespace", GatewayRoutersConfiguration.NAMESPACE);
configService = NacosFactory.createConfigService(properties);
return configService;
} catch (Exception e) {
log.error("创建ConfigService异常", e);
return null;
}
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
@@ -1,96 +0,0 @@
package com.jero.loader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
/**
* 动态更新路由网关service
* 1)实现一个Spring提供的事件推送接口ApplicationEventPublisherAware
* 2)提供动态路由的基础方法,可通过获取bean操作该类的方法。该类提供新增路由、更新路由、删除路由,然后实现发布的功能。
*
* @author zyf
*/
@Slf4j
@Service
public class DynamicRouteService implements ApplicationEventPublisherAware {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
@Autowired
private InMemoryRouteDefinitionRepository repository;
/**
* 发布事件
*/
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
/**
* 删除路由
*
* @param id
* @return
*/
public synchronized void delete(String id) {
try {
repository.delete(Mono.just(id)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 更新路由
*
* @param definition
* @return
*/
public synchronized String update(RouteDefinition definition) {
try {
log.info("gateway update route {}", definition);
delete(definition.getId());
} catch (Exception e) {
return "update fail,not find route routeId: " + definition.getId();
}
try {
repository.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
} catch (Exception e) {
return "update route fail";
}
}
/**
* 增加路由
*
* @param definition
* @return
*/
public synchronized String add(RouteDefinition definition) {
log.info("gateway add route {}", definition);
try {
repository.save(Mono.just(definition)).subscribe();
} catch (Exception e) {
log.error(e.toString());
}
return "success";
}
}
@@ -1,16 +0,0 @@
package com.jero.loader;
import lombok.Data;
@Data
public class GatewayRouteVo {
private String id;
private String name;
private String uri;
private String predicates;
private String filters;
private Integer stripPrefix;
private Integer retryable;
private Integer persist;
private Integer status;
}
@@ -1,38 +0,0 @@
package com.jero.loader;
import org.springframework.cloud.gateway.route.RouteDefinition;
import java.util.Objects;
/**
* 自定义RouteDefinition
* @author zyf
*/
public class MyRouteDefinition extends RouteDefinition {
/**
* 路由状态
*/
private Integer status;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
MyRouteDefinition that = (MyRouteDefinition) o;
return Objects.equals(status, that.status);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), status);
}
}
@@ -1,61 +0,0 @@
server:
port: 8080
spring:
application:
name: jero-gateway
cloud:
gateway:
discovery:
locator:
enabled: true
globalcors:
cors-configurations:
'[/**]':
allowCredentials: true
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
#如果启用nacos或者数据库配置请删除一下配置
routes:
- id: jero-demo
uri: lb://jero-demo
predicates:
- Path=/mock/**,/test/**,/bigscreen/template1/**,/bigscreen/template2/**
- id: jero-system
uri: lb://jero-system
predicates:
- Path=/sys/**,/eoa/**,/v1/**,/joa/**,/online/**,/bigscreen/**,/jmreport/**,/desform/**,/act/**,/plug-in/**,/generic/**
- id: jero-system-websocket
uri: lb:ws://jero-system
predicates:
- Path=/websocket/**,/eoaSocket/**,/newsWebsocket/**
- id: jero-demo-websocket
uri: lb:ws://jero-demo
predicates:
- Path=/vxeSocket/**
# 全局熔断降级配置
default-filters:
- name: Hystrix
args:
name: default
#转发地址
fallbackUri: 'forward:/fallback'
- name: Retry
args:
#重试次数,默认值是 3 次
retries: 3
#HTTP 的状态返回码
statuses: BAD_GATEWAY,BAD_REQUEST
#指定哪些方法的请求需要进行重试逻辑,默认值是 GET 方法
methods: GET,POST
# hystrix 信号量隔离,10秒后自动超时
hystrix:
enabled: true
shareSecurityContext: true
command:
default:
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 10000
@@ -1,47 +0,0 @@
# 以下@符号包裹的配置,均在父POM中进行定义.
# 在微服务环境下,该配置文件会先于application.yml加载
# 对应到nacos配置的data-id是 application.name(应用名称) + profiles.active(开发环境是dev)
spring:
profiles:
# 当前激活环境
active: @profile.name@
cloud:
#配置Bus id(远程推送事件)
bus:
id: ${spring.application.name}:${server.port}
nacos:
config:
# Nacos 认证用户
username: nacos
# Nacos 认证密码
password: nacos
# 命名空间 常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等
namespace: @config.namespace@
# 配置中心地址
server-addr: @config.server-addr@
# 配置对应的分组
group: @config.group@
# 配置nacos中的配置文件名称
prefix: jero-gateway
# 配置文件后缀
file-extension: yaml
# 支持多个共享 Data Id 的配置,优先级小于extension-configs,自定义 Data Id 配置 属性是个集合,内部由 Config POJO 组成。Config 有 3 个属性,分别是 dataId, group 以及 refresh
#shared-configs[0]:
#data-id: @prefix.name@-common.yaml # 配置文件名-Data Id
#group: @config.group@ # 默认为DEFAULT_GROUP
#refresh: false # 是否动态刷新,默认为false
discovery:
namespace: @config.namespace@
server-addr: @config.server-addr@
watch:
enabled: false
jero:
# 签名密钥串(前后端要一致)
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
# 文件限制后缀黑名单
fileSuffixLimits: 0x00,%00,\\00,.jsp,.exe,.php,.asp,.aspx,.jspx,.xml,.html,.js,.sh,.bin
# 跨站白名单
whiteUrls:
route:
config:
data-type: yml
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 -->
<property name="LOG_HOME" value="../logs" />
<!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />-->
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/jeroboot-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
</encoder>
</appender>
<!--myibatis log configure -->
<logger name="com.apache.ibatis" level="TRACE" />
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
@@ -1,65 +0,0 @@
<?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>jero-cloud-module</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jero-cloud-monitor</artifactId>
<dependencies>
<!--Spring Boot Admin Server监控服务端-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--安全模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
@@ -1,16 +0,0 @@
package com.jero.monitor;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 监控服务
*/
@SpringBootApplication
@EnableAdminServer
public class JeroMonitorApplication {
public static void main(String[] args) {
SpringApplication.run(JeroMonitorApplication.class);
}
}
@@ -1,52 +0,0 @@
package com.jero.monitor.config;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
/**
* @author scott
*/
@Configuration
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {
private final String adminContextPath;
public SecuritySecureConfig(AdminServerProperties adminServerProperties) {
this.adminContextPath = adminServerProperties.getContextPath();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 登录成功处理类
SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/");
http.authorizeRequests()
//静态文件允许访问
.antMatchers(adminContextPath + "/assets/**").permitAll()
//登录页面允许访问
.antMatchers(adminContextPath + "/login", "/css/**", "/js/**", "/image/*").permitAll()
//其他所有请求需要登录
.anyRequest().authenticated()
.and()
//登录页面配置,用于替换security默认页面
.formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and()
//登出页面配置,用于替换security默认页面
.logout().logoutUrl(adminContextPath + "/logout").and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers(
"/instances",
"/actuator/**"
);
}
}
@@ -1,41 +0,0 @@
server:
port: 9111
spring:
boot:
admin:
ui:
title: JeroCloud监控中心
client:
instance:
metadata:
tags:
environment: local
security:
user:
name: "admin"
password: "admin"
application:
name: jero-monitor
cloud:
nacos:
discovery:
server-addr: @config.server-addr@
metadata:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
# 服务端点检查
management:
trace:
http:
enabled: true
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
@@ -1,15 +0,0 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER jeroos@163.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /jero-cloud-nacos
WORKDIR /jero-cloud-nacos
EXPOSE 8848
ADD ./target/jero-cloud-nacos-2.5.0.jar ./
CMD sleep 5;java -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -jar jero-cloud-nacos-2.5.0.jar
@@ -1,75 +0,0 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>jero-cloud-module</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<artifactId>jero-cloud-nacos</artifactId>
<name>jero-cloud-nacos</name>
<description>nacos启动模块</description>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jeecg</id>
<name>jeecg Repository</name>
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-naming</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-istio</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-config</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-console</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -1,37 +0,0 @@
package com.alibaba.nacos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* Nacos 启动类
* 引用的nacos console 源码运行,简化开发
* 生产建议从官网下载最新版配置运行
* @author zyf
*/
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@ServletComponentScan
@EnableScheduling
public class JeroNacosApplication {
/**
* 是否单机模式启动
*/
private static String standalone = "true";
/**
* 是否开启鉴权
*/
private static String enabled = "false";
public static void main(String[] args) {
System.setProperty("nacos.standalone", standalone);
System.setProperty("nacos.core.auth.enabled", enabled);
System.setProperty("server.tomcat.basedir","logs");
//自定义启动端口号
System.setProperty("server.port","8848");
SpringApplication.run(JeroNacosApplication.class, args);
}
}
@@ -1,54 +0,0 @@
server:
servlet:
contextPath: /nacos
tomcat:
accesslog:
enabled: true
pattern: '%h %l %u %t "%r" %s %b %D %{User-Agent}i %{Request-Source}i'
basedir: ''
spring:
datasource:
platform: mysql
db:
num: 1
password:
'0': 123456
url:
'0': jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
user:
'0': root
management:
metrics:
export:
elastic:
enabled: false
influx:
enabled: false
nacos:
core:
auth:
caching:
enabled: true
default:
token:
expire:
seconds: 18000
secret:
key: SecretKey012345678901234567890123456789012345678901234567890123456789
enabled: false
system:
type: nacos
istio:
mcp:
server:
enabled: false
naming:
empty-service:
auto-clean: true
clean:
initial-delay-ms: 50000
period-time-ms: 30000
security:
ignore:
urls: /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-ui/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
standalone: true
@@ -1,111 +0,0 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>jero-cloud-module</artifactId>
<groupId>com.jero.boot</groupId>
<version>2.5.0</version>
</parent>
<artifactId>jero-cloud-sentinel</artifactId>
<name>jero-cloud-sentinel</name>
<description>sentinel启动模块</description>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jeecg</id>
<name>jeecg Repository</name>
<url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jeecgframework.cloud</groupId>
<artifactId>sentinel-dashboard</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-parameter-flow-control</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-api-gateway-adapter-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore-nio</artifactId>
<version>4.4.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -1,49 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* 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
*
* http://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.csp.sentinel.dashboard;
import com.alibaba.csp.sentinel.init.InitExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
/**
* Sentinel dashboard application.
*
* @author Carpenter Lee
*/
@SpringBootApplication
@Slf4j
public class JeroSentinelDashboardApplication {
public static void main(String[] args) {
System.setProperty("csp.sentinel.app.type", "1");
triggerSentinelInit();
ConfigurableApplicationContext application = SpringApplication.run(JeroSentinelDashboardApplication.class, args);
Environment env = application.getEnvironment();
String port = env.getProperty("server.port");
log.info("\n----------------------------------------------------------\n\t" +
"Application SentinelDashboard is running! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port + "/\n\t" +
"----------------------------------------------------------");
}
private static void triggerSentinelInit() {
new Thread(InitExecutor::doInit).start();
}
}

Some files were not shown because too many files have changed in this diff Show More