将检测时间设hi成5秒

This commit is contained in:
寻欢·李 2018-02-09 10:17:56 +08:00
commit 977e21bcb4
90 changed files with 1539 additions and 268 deletions

View File

@ -1,6 +1,23 @@
### 详细配置 wiki <p align="center">
<img src="https://img.shields.io/circleci/project/vuejs/vue/dev.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Spring%20Cloud-Edgware-blue.svg" alt="Coverage Status">
<img src="https://img.shields.io/badge/Spring%20Boot-1.5.9-blue.svg" alt="Downloads">
<img src="https://img.shields.io/badge/npm-v5.5.1-blue.svg" alt="Version">
<img src="https://img.shields.io/npm/l/vue.svg" alt="License">
</p>
<h2 align="center">Supporting lengleng</h2>
### 详细配置 wiki
https://gitee.com/log4j/pig/wikis/ https://gitee.com/log4j/pig/wikis/
### 视频教程
1. [课程介绍项目介绍](http://p3blpcsde.bkt.clouddn.com/1.mp4)
2. [环境搭建运行展示](http://p3blpcsde.bkt.clouddn.com/2.mp4)
3. Spring security oAuth2 源码详解 ...还在录
### now ### now
``` lua ``` lua
pig pig
@ -11,7 +28,9 @@ pig
├── pig-eureka -- 服务注册与发现[1025] ├── pig-eureka -- 服务注册与发现[1025]
├── pig-gateway -- ZUUL网关[9999] ├── pig-gateway -- ZUUL网关[9999]
├── pig-modules -- 微服务模块 ├── pig-modules -- 微服务模块
├ ├── pig-daemon-service -- 分布式调度中心[4060]
├ ├── pig-mc-service -- 消息中心[4050] ├ ├── pig-mc-service -- 消息中心[4050]
├ ├── pig-sso-client-demo -- 单点登录客户端示例[4040]
├ └── pig-upms-service -- 权限管理提供[4000] ├ └── pig-upms-service -- 权限管理提供[4000]
└── pig-visual -- 图形化模块 └── pig-visual -- 图形化模块
├── pig-monitor -- 服务状态监控、turbine [5001] ├── pig-monitor -- 服务状态监控、turbine [5001]
@ -20,6 +39,7 @@ pig
``` ```
### 已完成功能 ### 已完成功能
- 完善登录账号密码模式、短信验证码模式、社交账号模式均整合Spring security oAuth - 完善登录账号密码模式、短信验证码模式、社交账号模式均整合Spring security oAuth
- 单点登录基于Srping security oAuth 提供单点登录接口,方便其他系统对接
- 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 - 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
- 机构管理:配置系统组织机构(公司、部门、小组),树结构展现,可随意调整上下级。 - 机构管理:配置系统组织机构(公司、部门、小组),树结构展现,可随意调整上下级。
- 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 - 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
@ -27,6 +47,7 @@ pig
- 字典管理:对系统中经常使用的一些较为固定的数据进行维护,如:是否、男女、类别、级别等。 - 字典管理:对系统中经常使用的一些较为固定的数据进行维护,如:是否、男女、类别、级别等。
- 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 - 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
- 服务限流多种维度的流量控制服务、IP、用户等 - 服务限流多种维度的流量控制服务、IP、用户等
- 分库分表shardingdbc分库分表策略
- 数据权限: 使用mybatis对原查询做增强业务代码不用控制即可实现。 - 数据权限: 使用mybatis对原查询做增强业务代码不用控制即可实现。
- 文件系统: 支持FastDFS、七牛云扩展API几行代码实现上传下载 - 文件系统: 支持FastDFS、七牛云扩展API几行代码实现上传下载
- 消息中心:短信、邮件模板发送,几行代码实现发送 - 消息中心:短信、邮件模板发送,几行代码实现发送
@ -34,7 +55,9 @@ pig
- 代码生成前后端代码的生成支持Vue - 代码生成前后端代码的生成支持Vue
- 缓存管理基于Cache Cloud 保证Redis 的高可用 - 缓存管理基于Cache Cloud 保证Redis 的高可用
- 服务监控: Spring Boot Admin - 服务监控: Spring Boot Admin
- 链路追踪服务链路追踪日志保存到ELK支持数据可视化 - 分布式任务调度: 基于elastic-job的分布式文件系统zookeeper做调度中心
- zipkin链路追踪 数据保存ELK图形化展示
- pinpoint链路追踪 数据保存hbase图形化展示
欢迎加入QQ交流群互相学习 欢迎加入QQ交流群互相学习
一键加群:<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=5zWEvg5"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png"></a> 一键加群:<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=5zWEvg5"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png"></a>
@ -45,6 +68,7 @@ pig
![image](http://p0hpm86wj.bkt.clouddn.com/3.png) ![image](http://p0hpm86wj.bkt.clouddn.com/3.png)
![image](http://p0hpm86wj.bkt.clouddn.com/4.png) ![image](http://p0hpm86wj.bkt.clouddn.com/4.png)
![image](http://p0hpm86wj.bkt.clouddn.com/5.png) ![image](http://p0hpm86wj.bkt.clouddn.com/5.png)
![image](http://p0hpm86wj.bkt.clouddn.com/34.png)
![image](http://p0hpm86wj.bkt.clouddn.com/21.png) ![image](http://p0hpm86wj.bkt.clouddn.com/21.png)
![image](http://p0hpm86wj.bkt.clouddn.com/22.png) ![image](http://p0hpm86wj.bkt.clouddn.com/22.png)
![image](http://p0hpm86wj.bkt.clouddn.com/23.png) ![image](http://p0hpm86wj.bkt.clouddn.com/23.png)

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,7 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
public class PigWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator { public class PigWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {
/** /**
* @param e spring security内部异常 * @param e spring security内部异常
* @return 经过处理的异常信息 * @return 经过处理的异常信息

View File

@ -26,6 +26,7 @@ public class MobileAuthenticationFilter extends AbstractAuthenticationProcessing
super(new AntPathRequestMatcher(SecurityConstants.MOBILE_TOKEN_URL, "POST")); super(new AntPathRequestMatcher(SecurityConstants.MOBILE_TOKEN_URL, "POST"));
} }
@Override
public Authentication attemptAuthentication(HttpServletRequest request, public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException { HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) { if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {

View File

@ -30,6 +30,7 @@ public class MobileAuthenticationToken extends AbstractAuthenticationToken {
super.setAuthenticated(true); super.setAuthenticated(true);
} }
@Override
public Object getPrincipal() { public Object getPrincipal() {
return this.principal; return this.principal;
} }
@ -39,6 +40,7 @@ public class MobileAuthenticationToken extends AbstractAuthenticationToken {
return null; return null;
} }
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) { if (isAuthenticated) {
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

@ -29,6 +29,7 @@ import java.io.PrintWriter;
*/ */
@Component @Component
public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler { public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
public static final String BASIC_ = "Basic ";
private Logger logger = LoggerFactory.getLogger(getClass()); private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired @Autowired
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@ -49,7 +50,7 @@ public class MobileLoginSuccessHandler implements AuthenticationSuccessHandler {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
String header = request.getHeader("Authorization"); String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Basic ")) { if (header == null || !header.startsWith(BASIC_)) {
throw new UnapprovedClientAuthenticationException("请求头中client信息为空"); throw new UnapprovedClientAuthenticationException("请求头中client信息为空");
} }

View File

@ -16,12 +16,5 @@ import java.util.Map;
public class SocialConnectView extends AbstractView { public class SocialConnectView extends AbstractView {
@Override @Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=UTF-8");
if (model.get("connection") == null) {
response.getWriter().write("<h3>解绑成功</h3>");
} else {
response.getWriter().write("<h3>绑定成功</h3>");
}
} }
} }

View File

@ -34,7 +34,7 @@ public class SocialConnectionStatusView extends AbstractView {
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, List<Connection<?>>> connections = (Map<String, List<Connection<?>>>) model.get("connectionMap"); Map<String, List<Connection<?>>> connections = (Map<String, List<Connection<?>>>) model.get("connectionMap");
Map<String, Boolean> result = new HashMap<>(); Map<String, Boolean> result = new HashMap<>(8);
for (String key : connections.keySet()) { for (String key : connections.keySet()) {
result.put(key, CollectionUtils.isNotEmpty(connections.get(key))); result.put(key, CollectionUtils.isNotEmpty(connections.get(key)));
} }

View File

@ -33,9 +33,7 @@ import java.io.PrintWriter;
public class SocialLoginSuccessHandler implements AuthenticationSuccessHandler { public class SocialLoginSuccessHandler implements AuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass()); private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired @Autowired
private ObjectMapper objectMapper; private AuthServerConfig authServerConfig;
@Autowired
private AuthServerConfig AuthServerConfig;
@Autowired @Autowired
private ClientDetailsService clientDetailsService; private ClientDetailsService clientDetailsService;
@Autowired @Autowired
@ -52,8 +50,8 @@ public class SocialLoginSuccessHandler implements AuthenticationSuccessHandler {
@Override @Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
try { try {
String clientId = AuthServerConfig.getClientId(); String clientId = authServerConfig.getClientId();
String clientSecret = AuthServerConfig.getClientSecret(); String clientSecret = authServerConfig.getClientSecret();
JSONObject params = new JSONObject(); JSONObject params = new JSONObject();
params.put("clientId", clientId); params.put("clientId", clientId);

View File

@ -51,7 +51,7 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
clients.inMemory() clients.inMemory()
.withClient(authServerConfig.getClientId()) .withClient(authServerConfig.getClientId())
.secret(authServerConfig.getClientSecret()) .secret(authServerConfig.getClientSecret())
.authorizedGrantTypes(SecurityConstants.REFRESH_TOKEN, SecurityConstants.PASSWORD) .authorizedGrantTypes(SecurityConstants.REFRESH_TOKEN, SecurityConstants.PASSWORD,SecurityConstants.AUTHORIZATION_CODE)
.scopes(authServerConfig.getScope()); .scopes(authServerConfig.getScope());
} }
@ -70,7 +70,7 @@ public class PigAuthorizationConfig extends AuthorizationServerConfigurerAdapter
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security security
.allowFormAuthenticationForClients() .allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()") .tokenKeyAccess("isAuthenticated()")
.checkTokenAccess("permitAll()"); .checkTokenAccess("permitAll()");
} }

View File

@ -30,6 +30,7 @@ public class MobileAuthenticationToken extends AbstractAuthenticationToken {
super.setAuthenticated(true); super.setAuthenticated(true);
} }
@Override
public Object getPrincipal() { public Object getPrincipal() {
return this.principal; return this.principal;
} }
@ -39,6 +40,7 @@ public class MobileAuthenticationToken extends AbstractAuthenticationToken {
return null; return null;
} }
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
if (isAuthenticated) { if (isAuthenticated) {
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

@ -1,6 +1,7 @@
package com.github.pig.auth.util; package com.github.pig.auth.util;
import com.github.pig.common.constant.CommonConstant; import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.vo.SysRole; import com.github.pig.common.vo.SysRole;
import com.github.pig.common.vo.UserVo; import com.github.pig.common.vo.UserVo;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -37,6 +38,7 @@ public class UserDetailsImpl implements UserDetails {
for (SysRole role : roleList) { for (SysRole role : roleList) {
authorityList.add(new SimpleGrantedAuthority(role.getRoleCode())); authorityList.add(new SimpleGrantedAuthority(role.getRoleCode()));
} }
authorityList.add(new SimpleGrantedAuthority(SecurityConstants.BASE_ROLE));
return authorityList; return authorityList;
} }

View File

@ -18,6 +18,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -151,7 +151,7 @@
</logger> </logger>
<!-- root级别 DEBUG --> <!-- root级别 DEBUG -->
<root level="DEBUG"> <root level="INFO">
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
<!-- 文件输出 --> <!-- 文件输出 -->

View File

@ -1,12 +1,8 @@
package com.github.pig.common.bean.aop; package com.github.pig.common.bean.aop;
import com.github.pig.common.constant.SecurityConstants; import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.util.R;
import com.github.pig.common.util.UserUtils; import com.github.pig.common.util.UserUtils;
import com.github.pig.common.util.exception.CheckException;
import com.github.pig.common.util.exception.UnloginException;
import com.github.pig.common.vo.UserVo; import com.github.pig.common.vo.UserVo;
import com.xiaoleilu.hutool.lang.Console;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
@ -22,7 +18,6 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional;
/** /**
* @author lengleng * @author lengleng

View File

@ -15,4 +15,14 @@ public interface MqQueueConstant {
* 发送短信验证码队列 * 发送短信验证码队列
*/ */
String MOBILE_CODE_QUEUE = "mobile_code_queue"; String MOBILE_CODE_QUEUE = "mobile_code_queue";
/**
* 服务状态队列
*/
String SERVICE_STATUS_CHANGE = "service_status_change";
/**
* zipkin 队列
*/
String ZIPLIN_NAME_QUEUE = "zipkin";
} }

View File

@ -5,6 +5,14 @@ package com.github.pig.common.constant;
* @date 2017-12-18 * @date 2017-12-18
*/ */
public interface SecurityConstants { public interface SecurityConstants {
/**
* 基础角色
*/
String BASE_ROLE = "ROLE_USER";
/**
* 授权码模式
*/
String AUTHORIZATION_CODE = "authorization_code";
/** /**
* 密码模式 * 密码模式
*/ */
@ -81,11 +89,6 @@ public interface SecurityConstants {
*/ */
String TOKEN_USER_DETAIL = "token-user-detail"; String TOKEN_USER_DETAIL = "token-user-detail";
/**
* 认证服务的SERVICEIDzuul 配置的对应
*/
String AUTH_SERVICE_ID = "auth-service";
/** /**
* 默认的social的登录地址 * 默认的social的登录地址
*/ */

View File

@ -0,0 +1,18 @@
package com.github.pig.common.constant;
/**
* @author lengleng
* @date 2018/1/25
* 服务名称
*/
public interface ServiceNameConstant {
/**
* 认证服务的SERVICEIDzuul 配置的对应
*/
String AUTH_SERVICE = "pig-auth";
/**
* UMPS模块
*/
String UMPS_SERVICE = "pig-upms-service";
}

View File

@ -6,6 +6,9 @@ package com.github.pig.common.constant.enums;
* 短信通道枚举 * 短信通道枚举
*/ */
public enum EnumSmsChannel { public enum EnumSmsChannel {
/**
* 阿里大鱼短信通道
*/
ALIYUN("ALIYUN_SMS", "阿里大鱼"); ALIYUN("ALIYUN_SMS", "阿里大鱼");
/** /**
* 通道名称 * 通道名称

View File

@ -1,5 +1,8 @@
package com.github.pig.common.entity; package com.github.pig.common.entity;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -18,7 +21,8 @@ public class SysLog implements Serializable {
/** /**
* 编号 * 编号
*/ */
private Integer id; @TableId(type = IdType.ID_WORKER)
private Long id;
/** /**
* 日志类型 * 日志类型
*/ */
@ -79,11 +83,11 @@ public class SysLog implements Serializable {
*/ */
private String serviceId; private String serviceId;
public Integer getId() { public Long getId() {
return id; return id;
} }
public void setId(Integer id) { public void setId(Long id) {
this.id = id; this.id = id;
} }

View File

@ -1,6 +1,6 @@
package com.github.pig.common.util; package com.github.pig.common.util;
import com.github.pig.common.util.exception.CheckException; import com.github.pig.common.util.exception.CheckedException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
@ -25,29 +25,29 @@ public class Assert {
* 校验对象 * 校验对象
* @param object 待校验对象 * @param object 待校验对象
* @param groups 待校验的组 * @param groups 待校验的组
* @throws CheckException 校验不通过则报RRException异常 * @throws CheckedException 校验不通过则报RRException异常
*/ */
public static void validateEntity(Object object, Class<?>... groups) public static void validateEntity(Object object, Class<?>... groups)
throws CheckException { throws CheckedException {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups); Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) { if (!constraintViolations.isEmpty()) {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
for(ConstraintViolation<Object> constraint: constraintViolations){ for(ConstraintViolation<Object> constraint: constraintViolations){
msg.append(constraint.getMessage()).append("<br>"); msg.append(constraint.getMessage()).append("<br>");
} }
throw new CheckException(msg.toString()); throw new CheckedException(msg.toString());
} }
} }
public static void isBlank(String str, String message) { public static void isBlank(String str, String message) {
if (StringUtils.isBlank(str)) { if (StringUtils.isBlank(str)) {
throw new CheckException(message); throw new CheckedException(message);
} }
} }
public static void isNull(Object object, String message) { public static void isNull(Object object, String message) {
if (object == null) { if (object == null) {
throw new CheckException(message); throw new CheckedException(message);
} }
} }
} }

View File

@ -1,30 +0,0 @@
package com.github.pig.common.util.exception;
/**
* @author lengleng
* @date 😴2017年12月21日20:44:38
*/
public class CheckException extends RuntimeException {
private static final long serialVersionUID = 1L;
public CheckException() {
}
public CheckException(String message) {
super(message);
}
public CheckException(Throwable cause) {
super(cause);
}
public CheckException(String message, Throwable cause) {
super(message, cause);
}
public CheckException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,30 @@
package com.github.pig.common.util.exception;
/**
* @author lengleng
* @date 😴2017年12月21日20:44:38
*/
public class CheckedException extends RuntimeException {
private static final long serialVersionUID = 1L;
public CheckedException() {
}
public CheckedException(String message) {
super(message);
}
public CheckedException(Throwable cause) {
super(cause);
}
public CheckedException(String message, Throwable cause) {
super(message, cause);
}
public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -49,6 +49,15 @@ public class UserVo implements Serializable {
*/ */
private String avatar; private String avatar;
/**
* 部门ID
*/
private Integer deptId;
/**
* 部门名称
*/
private String deptName;
/** /**
* 角色列表 * 角色列表
*/ */
@ -133,4 +142,20 @@ public class UserVo implements Serializable {
public void setAvatar(String avatar) { public void setAvatar(String avatar) {
this.avatar = avatar; this.avatar = avatar;
} }
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
} }

View File

@ -17,9 +17,12 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka
--- ---
spring: spring:
profiles: prd profiles: prd

View File

@ -20,6 +20,6 @@ eureka:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
instance: instance:
hostname: localhost hostname: localhost
# server: #配置属性,但由于 Eureka 自我保护模式以及心跳周期长的原因,经常会遇到 Eureka Server 不剔除已关停的节点的问题 server: #配置属性,但由于 Eureka 自我保护模式以及心跳周期长的原因,经常会遇到 Eureka Server 不剔除已关停的节点的问题
# enable-self-preservation: false enable-self-preservation: false
# eviction-interval-timer-in-ms: 100 eviction-interval-timer-in-ms: 5000

View File

@ -63,15 +63,7 @@
<!--zipkin--> <!--zipkin-->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-stream</artifactId> <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,8 +1,8 @@
package com.github.pig.gateway.config; package com.github.pig.gateway.componet.config;
import com.github.pig.common.bean.config.FilterUrlsPropertiesConifg; import com.github.pig.common.bean.config.FilterUrlsPropertiesConifg;
import com.github.pig.gateway.componet.PigAccessDeniedHandler; import com.github.pig.gateway.componet.filter.ValidateCodeFilter;
import com.github.pig.gateway.filter.ValidateCodeFilter; import com.github.pig.gateway.componet.handler.PigAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;

View File

@ -0,0 +1,73 @@
package com.github.pig.gateway.componet.fallback;
import com.github.pig.common.constant.ServiceNameConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* @author lengleng
* @date 2018/1/25
* Auth 模块异常回调
*/
@Slf4j
@Component
public class AuthFallbackProvider implements FallbackProvider {
@Override
public ClientHttpResponse fallbackResponse(Throwable cause) {
log.error("调用:{} 异常:{}", getRoute(), cause.getMessage());
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() {
return HttpStatus.SERVICE_UNAVAILABLE;
}
@Override
public int getRawStatusCode() {
return HttpStatus.SERVICE_UNAVAILABLE.value();
}
@Override
public String getStatusText() {
return HttpStatus.SERVICE_UNAVAILABLE.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() {
if (cause != null && cause.getMessage() != null) {
return new ByteArrayInputStream(cause.getMessage().getBytes());
} else {
return new ByteArrayInputStream("授权模块不可用".getBytes());
}
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
@Override
public String getRoute() {
return ServiceNameConstant.AUTH_SERVICE;
}
@Override
public ClientHttpResponse fallbackResponse() {
return fallbackResponse(null);
}
}

View File

@ -1,18 +1,17 @@
package com.github.pig.gateway.componet; package com.github.pig.gateway.componet.fallback;
import com.github.pig.common.constant.SecurityConstants; import com.github.pig.common.constant.ServiceNameConstant;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.Route; import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator; import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
/** /**
* @author lengleng * @author lengleng
* @date 2017/12/28 * @date 2017/12/28
@ -34,7 +33,7 @@ public class RegistrySwaggerResourcesProvider implements SwaggerResourcesProvide
List<Route> routes = routeLocator.getRoutes(); List<Route> routes = routeLocator.getRoutes();
routes.forEach(route -> { routes.forEach(route -> {
//授权不维护到swagger //授权不维护到swagger
if (!StringUtils.contains(route.getId(), SecurityConstants.AUTH_SERVICE_ID)){ if (!StringUtils.contains(route.getId(), ServiceNameConstant.AUTH_SERVICE)){
resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs"))); resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs")));
} }
}); });

View File

@ -0,0 +1,73 @@
package com.github.pig.gateway.componet.fallback;
import com.github.pig.common.constant.ServiceNameConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* @author lengleng
* @date 2018/1/25
* UPMS 模块异常回调
*/
@Slf4j
@Component
public class UpmsFallbackProvider implements FallbackProvider {
@Override
public ClientHttpResponse fallbackResponse(Throwable cause) {
log.error("调用:{} 异常:{}", getRoute(), cause.getMessage());
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() {
return HttpStatus.SERVICE_UNAVAILABLE;
}
@Override
public int getRawStatusCode() {
return HttpStatus.SERVICE_UNAVAILABLE.value();
}
@Override
public String getStatusText() {
return HttpStatus.SERVICE_UNAVAILABLE.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() {
if (cause != null && cause.getMessage() != null) {
return new ByteArrayInputStream(cause.getMessage().getBytes());
} else {
return new ByteArrayInputStream("权限管理模块不可用".getBytes());
}
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
@Override
public String getRoute() {
return ServiceNameConstant.UMPS_SERVICE;
}
@Override
public ClientHttpResponse fallbackResponse() {
return fallbackResponse(null);
}
}

View File

@ -1,4 +1,4 @@
package com.github.pig.gateway.filter; package com.github.pig.gateway.componet.filter;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;

View File

@ -1,4 +1,4 @@
package com.github.pig.gateway.filter; package com.github.pig.gateway.componet.filter;
import com.github.pig.gateway.service.LogSendService; import com.github.pig.gateway.service.LogSendService;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
@ -18,8 +18,6 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst
*/ */
@Component @Component
public class ErrorHandlerFilter extends ZuulFilter { public class ErrorHandlerFilter extends ZuulFilter {
private static final Logger logger = LoggerFactory.getLogger(ValidateCodeFilter.class);
@Autowired @Autowired
private LogSendService logSendService; private LogSendService logSendService;

View File

@ -1,11 +1,8 @@
package com.github.pig.gateway.filter; package com.github.pig.gateway.componet.filter;
import com.github.pig.gateway.service.LogSendService; import com.github.pig.gateway.service.LogSendService;
import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,4 +1,4 @@
package com.github.pig.gateway.filter; package com.github.pig.gateway.componet.filter;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant; import com.github.pig.common.constant.CommonConstant;

View File

@ -1,4 +1,4 @@
package com.github.pig.gateway.componet; package com.github.pig.gateway.componet.handler;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pig.common.constant.CommonConstant; import com.github.pig.common.constant.CommonConstant;

View File

@ -1,11 +1,9 @@
package com.github.pig.gateway.service.impl; package com.github.pig.gateway.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.github.pig.common.constant.CommonConstant; import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant; import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.entity.SysLog; import com.github.pig.common.entity.SysLog;
import com.github.pig.common.util.UserUtils; import com.github.pig.common.util.UserUtils;
import com.github.pig.common.vo.ErrorPojo;
import com.github.pig.common.vo.LogVo; import com.github.pig.common.vo.LogVo;
import com.github.pig.gateway.service.LogSendService; import com.github.pig.gateway.service.LogSendService;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;
@ -70,7 +68,7 @@ public class LogSendServiceImpl implements LogSendService {
InputStream inputStream = requestContext.getResponseDataStream(); InputStream inputStream = requestContext.getResponseDataStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream stream1 = null; InputStream stream1 = null;
InputStream stream2 = null; InputStream stream2;
byte[] buffer = IoUtil.readBytes(inputStream); byte[] buffer = IoUtil.readBytes(inputStream);
try { try {
baos.write(buffer); baos.write(buffer);
@ -78,9 +76,8 @@ public class LogSendServiceImpl implements LogSendService {
stream1 = new ByteArrayInputStream(baos.toByteArray()); stream1 = new ByteArrayInputStream(baos.toByteArray());
stream2 = new ByteArrayInputStream(baos.toByteArray()); stream2 = new ByteArrayInputStream(baos.toByteArray());
String resp = IoUtil.read(stream1, CommonConstant.UTF8); String resp = IoUtil.read(stream1, CommonConstant.UTF8);
ErrorPojo error = JSONObject.parseObject(resp, ErrorPojo.class);
log.setType(CommonConstant.STATUS_LOCK); log.setType(CommonConstant.STATUS_LOCK);
log.setException(error.getMessage()); log.setException(resp);
requestContext.setResponseDataStream(stream2); requestContext.setResponseDataStream(stream2);
} catch (IOException e) { } catch (IOException e) {
logger.error("响应流解析异常:", e); logger.error("响应流解析异常:", e);

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.toolkit.StringUtils;
import com.github.pig.common.vo.MenuVo; import com.github.pig.common.vo.MenuVo;
import com.github.pig.gateway.feign.MenuService; import com.github.pig.gateway.feign.MenuService;
import com.github.pig.gateway.service.PermissionService; import com.github.pig.gateway.service.PermissionService;
import com.xiaoleilu.hutool.util.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
@ -11,6 +12,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -36,7 +38,15 @@ public class PermissionServiceImpl implements PermissionService {
boolean hasPermission = false; boolean hasPermission = false;
if (principal != null) { if (principal != null) {
Set<MenuVo> urls = menuService.findMenuByRole(grantedAuthorityList.get(0).getAuthority()); if (CollectionUtil.isEmpty(grantedAuthorityList)) {
return hasPermission;
}
Set<MenuVo> urls = new HashSet<>();
for (SimpleGrantedAuthority authority : grantedAuthorityList) {
urls.addAll(menuService.findMenuByRole(authority.getAuthority()));
}
for (MenuVo menu : urls) { for (MenuVo menu : urls) {
if (StringUtils.isNotEmpty(menu.getUrl()) && antPathMatcher.match(menu.getUrl(), request.getRequestURI()) if (StringUtils.isNotEmpty(menu.getUrl()) && antPathMatcher.match(menu.getUrl(), request.getRequestURI())
&& request.getMethod().equalsIgnoreCase(menu.getMethod())) { && request.getMethod().equalsIgnoreCase(menu.getMethod())) {

View File

@ -1,6 +1,7 @@
package com.github.pig.gateway.util; package com.github.pig.gateway.util;
import com.github.pig.common.constant.CommonConstant; import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.SecurityConstants;
import com.github.pig.common.vo.SysRole; import com.github.pig.common.vo.SysRole;
import com.github.pig.common.vo.UserVo; import com.github.pig.common.vo.UserVo;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -37,6 +38,7 @@ public class UserDetailsImpl implements UserDetails {
for (SysRole role : roleList) { for (SysRole role : roleList) {
authorityList.add(new SimpleGrantedAuthority(role.getRoleCode())); authorityList.add(new SimpleGrantedAuthority(role.getRoleCode()));
} }
authorityList.add(new SimpleGrantedAuthority(SecurityConstants.BASE_ROLE));
return authorityList; return authorityList;
} }

View File

@ -17,6 +17,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -0,0 +1,98 @@
<?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>
<groupId>com.github.pig</groupId>
<artifactId>pig-daemon-service</artifactId>
<version>${pig.version}</version>
<packaging>jar</packaging>
<name>pig-daemon-service</name>
<description>后台跑批定时任务模块</description>
<parent>
<groupId>com.github.pig</groupId>
<artifactId>pig-modules</artifactId>
<version>${pig.version}</version>
</parent>
<properties>
<elastic-job.version>2.1.5</elastic-job.version>
<curator.version>2.10.0</curator.version>
</properties>
<dependencies>
<dependency>
<groupId>com.github.pig</groupId>
<artifactId>pig-common</artifactId>
<version>${pig.version}</version>
</dependency>
<dependency>
<groupId>com.github.xjzrc.spring.boot</groupId>
<artifactId>elastic-job-lite-spring-boot-starter</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<!--去掉默认的tomcat-jdbc的依赖-->
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--HikariCP连接池-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
package com.github.pig.daemon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author lengleng
* @date 2018年02月07日20:35:35
* 分布式任务调度模块
*/
@EnableDiscoveryClient
@SpringBootApplication
public class PigDaemonApplication {
public static void main(String[] args) {
SpringApplication.run(PigDaemonApplication.class, args);
}
}

View File

@ -0,0 +1,29 @@
package com.github.pig.daemon.job;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.zen.elasticjob.spring.boot.annotation.ElasticJobConfig;
import lombok.extern.slf4j.Slf4j;
/**
* @author lengleng
* @date 2018/2/7
* 测试Job
*/
@Slf4j
@ElasticJobConfig(cron = "0/2 * * * * ?", shardingTotalCount = 3,
shardingItemParameters = "0=pig1,1=pig2,2=pig3",
startedTimeoutMilliseconds = 5000L,
completedTimeoutMilliseconds = 10000L,
eventTraceRdbDataSource = "dataSource")
public class DemoSimpleJob implements SimpleJob {
/**
* 业务执行逻辑
*
* @param shardingContext 分片信息
*/
@Override
public void execute(ShardingContext shardingContext) {
log.info("--------------");
}
}

View File

@ -0,0 +1,34 @@
spring:
application:
name: pig-daemon-service
profiles:
active: dev
cloud:
config:
fail-fast: true
discovery:
service-id: pig-config-server
enabled: true
profile: ${spring.profiles.active}
label: ${spring.profiles.active}
---
spring:
profiles: dev
eureka:
instance:
prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client:
serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka
---
spring:
profiles: prd
eureka:
instance:
prefer-ip-address: true
client:
serviceUrl:
defaultZone: http://pig:gip6666@pig-eureka:1025/eureka

View File

@ -33,8 +33,8 @@
<groupId>com.aliyun.taobao</groupId> <groupId>com.aliyun.taobao</groupId>
<artifactId>alidayu-sms</artifactId> <artifactId>alidayu-sms</artifactId>
<version>1.0</version> <version>1.0</version>
<!--<scope>system</scope>--> <scope>system</scope>
<!--<systemPath>${basedir}/src/main/resources/lib/alidayu-sms-1.0.jar</systemPath>--> <systemPath>${basedir}/src/main/resources/lib/alidayu-sms-1.0.jar</systemPath>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -0,0 +1,30 @@
package com.github.pig.mc.listener;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.mc.handler.SmsMessageHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author lengleng
* @date 2018年01月25日15:59:00
* 监听服务状态改变发送请求
*/
@Slf4j
@Component
@RabbitListener(queues = MqQueueConstant.SERVICE_STATUS_CHANGE)
public class ServiceChangeReceiveListener {
@RabbitHandler
public void receive(MobileMsgTemplate mobileMsgTemplate) {
long startTime = System.currentTimeMillis();
log.info("消息中心接收到短信发送请求-> 手机号:{} -> 验证码: {} ", mobileMsgTemplate.getMobile(), mobileMsgTemplate.getText());
long useTime = System.currentTimeMillis() - startTime;
log.info("调用 {} 短信网关处理完毕,耗时 {}毫秒", mobileMsgTemplate.getType(), useTime);
}
}

View File

@ -6,6 +6,9 @@ package com.github.pig.mc.utils.sms;
* 短信通道模板 * 短信通道模板
*/ */
public enum EnumSmsChannelTemplate { public enum EnumSmsChannelTemplate {
/**
* 登录验证
*/
LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证"); LOGIN_NAME_LOGIN("loginCodeChannel", "登录验证");
/** /**
* 模板名称 * 模板名称

View File

@ -17,6 +17,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -0,0 +1,47 @@
<?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>
<groupId>com.github.pig</groupId>
<artifactId>pig-sso-client-demo</artifactId>
<version>${pig.version}</version>
<packaging>jar</packaging>
<name>pig-sso-client-demo</name>
<description>单点登录客户端</description>
<parent>
<groupId>com.github.pig</groupId>
<artifactId>pig-modules</artifactId>
<version>${pig.version}</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
package com.github.pig.sso;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author lengleng
* @date 2018年01月27日13:00:09
* 单点登录客户端
*/
@EnableOAuth2Sso
@SpringBootApplication
public class PigSsoClientDemoApplication {
public static void main(String[] args) {
SpringApplication.run(PigSsoClientDemoApplication.class, args);
}
}

View File

@ -0,0 +1,26 @@
package com.github.pig.sso.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
/**
* @author lengleng
* @date 2018年1月31日23:15:08
* 当前配置 暴露监控信息
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable();
}
}

View File

@ -0,0 +1,18 @@
package com.github.pig.sso.controller;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lengleng
* @date 2018/1/27
* demo controller
*/
@RestController
public class DemoController {
@GetMapping("/user")
public Authentication user(Authentication authentication) {
return authentication;
}
}

View File

@ -0,0 +1,60 @@
server:
port: 4040
context-path: /sso1
#监控短点配置
management:
security:
enabled: false
endpoints:
actuator:
enabled: true
shutdown:
enabled: false
security:
oauth2:
client:
client-id: pig
client-secret: pig
user-authorization-uri: http://localhost:3000/oauth/authorize
access-token-uri: http://localhost:3000/oauth/token
scope: server
resource:
jwt:
key-uri: http://localhost:3000/oauth/token_key
spring:
application:
name: pig-sso-client-demo
profiles:
active: dev
redis:
remote: true #是否是cachecloud 获取
host: 106.14.69.75
port: 6381
password:
logging:
config: classpath:logback.xml
---
spring:
profiles: dev
eureka:
instance:
prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client:
serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka
---
spring:
profiles: prd
eureka:
instance:
prefer-ip-address: true
client:
serviceUrl:
defaultZone: http://pig:gip6666@pig-eureka:1025/eureka

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<property name="appname" value="pig"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="logs/ev_cmdb"/>
<!-- 按照每天生成日志文件 -->
<appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${appname}.log.%d{yyyy-MM-dd}.log
</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} 【%X{user}】[%thread] %-5level %logger{50} -%msg%n
</pattern>
</layout>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- To enable JMX Management -->
<jmxConfigurator/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} 【%X{user}】 [%thread] %-5level %logger{36} -%msg%n</pattern>
</encoder>
</appender>
<logger name="com.github.pig" level="debug">
<!-- wenjie delete <appender-ref ref="file" /> <appender-ref ref="console"
/> -->
</logger>
<root level="DEBUG">
<!--
<appender-ref ref="file" />
-->
<appender-ref ref="console"/>
</root>
</configuration>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="http://localhost:4040/user">hhhhhh</a>
</body>
</html>

View File

@ -45,6 +45,11 @@
<groupId>com.zaxxer</groupId> <groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId> <artifactId>HikariCP</artifactId>
</dependency> </dependency>
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-core-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!--myabtis-plus 代码生成依赖--> <!--myabtis-plus 代码生成依赖-->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
@ -68,6 +73,11 @@
<artifactId>kaptcha</artifactId> <artifactId>kaptcha</artifactId>
<version>0.0.9</version> <version>0.0.9</version>
</dependency> </dependency>
<!--zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -31,4 +31,19 @@ public class RabbitConfig {
public Queue initMobileCodeQueue() { public Queue initMobileCodeQueue() {
return new Queue(MqQueueConstant.MOBILE_CODE_QUEUE); return new Queue(MqQueueConstant.MOBILE_CODE_QUEUE);
} }
/**
* 初始化服务状态改变队列
*
* @return
*/
@Bean
public Queue initServiceStatusChangeQueue() {
return new Queue(MqQueueConstant.SERVICE_STATUS_CHANGE);
}
@Bean
public Queue initZipkinQueue() {
return new Queue(MqQueueConstant.ZIPLIN_NAME_QUEUE);
}
} }

View File

@ -5,6 +5,7 @@ import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.entity.SysLog; import com.github.pig.common.entity.SysLog;
import com.github.pig.common.util.UserUtils; import com.github.pig.common.util.UserUtils;
import com.github.pig.common.vo.LogVo; import com.github.pig.common.vo.LogVo;
import com.xiaoleilu.hutool.util.RandomUtil;
import org.slf4j.MDC; import org.slf4j.MDC;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
@ -25,7 +26,6 @@ public class LogReceiveListener {
@RabbitHandler @RabbitHandler
public void receive(LogVo logVo) { public void receive(LogVo logVo) {
System.out.println(logVo.getSysLog());
SysLog sysLog = logVo.getSysLog(); SysLog sysLog = logVo.getSysLog();
String username = UserUtils.getUserName(logVo.getToken()); String username = UserUtils.getUserName(logVo.getToken());
MDC.put(KEY_USER, username); MDC.put(KEY_USER, username);

View File

@ -46,7 +46,7 @@ public class LogController extends BaseController {
* @return success/false * @return success/false
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public R<Boolean> delete(@PathVariable Integer id) { public R<Boolean> delete(@PathVariable Long id) {
return new R<>(sysLogService.updateByLogId(id)); return new R<>(sysLogService.updateByLogId(id));
} }
} }

View File

@ -71,13 +71,12 @@ public class RoleController extends BaseController {
/** /**
* 获取角色列表 * 获取角色列表
* *
* @param deptId 部门ID
* @return 角色列表 * @return 角色列表
*/ */
@GetMapping("/roleList") @GetMapping("/roleList/{deptId}")
public List<SysRole> roleList() { public List<SysRole> roleList(@PathVariable Integer deptId) {
SysRole condition = new SysRole(); return sysRoleService.selectListByDeptId(deptId);
condition.setDelFlag(CommonConstant.STATUS_NORMAL);
return sysRoleService.selectList(new EntityWrapper<>(condition));
} }

View File

@ -15,6 +15,8 @@ import com.github.pig.common.web.BaseController;
import com.luhuiguo.fastdfs.domain.StorePath; import com.luhuiguo.fastdfs.domain.StorePath;
import com.luhuiguo.fastdfs.service.FastFileStorageClient; import com.luhuiguo.fastdfs.service.FastFileStorageClient;
import com.xiaoleilu.hutool.io.FileUtil; import com.xiaoleilu.hutool.io.FileUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -60,8 +62,8 @@ public class UserController extends BaseController {
* @return 用户信息 * @return 用户信息
*/ */
@GetMapping("/{id}") @GetMapping("/{id}")
public SysUser user(@PathVariable Integer id) { public UserVo user(@PathVariable Integer id) {
return userService.selectById(id); return userService.selectUserVoById(id);
} }
/** /**
@ -70,6 +72,8 @@ public class UserController extends BaseController {
* @param id ID * @param id ID
* @return R * @return R
*/ */
@ApiOperation(value="删除用户", notes="根据ID删除用户")
@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Integer")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public R<Boolean> userDel(@PathVariable Integer id) { public R<Boolean> userDel(@PathVariable Integer id) {
SysUser sysUser = userService.selectById(id); SysUser sysUser = userService.selectById(id);

View File

@ -24,4 +24,12 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
* @return List * @return List
*/ */
List<Object> selectRolePage(Query<Object> query, Map<String, Object> condition); List<Object> selectRolePage(Query<Object> query, Map<String, Object> condition);
/**
* 通过部门ID查询角色列表
*
* @param deptId 部门ID
* @return 角色列表
*/
List<SysRole> selectListByDeptId(Integer deptId);
} }

View File

@ -49,4 +49,11 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
* @return userVo * @return userVo
*/ */
UserVo selectUserVoByOpenId(String openId); UserVo selectUserVoByOpenId(String openId);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return userVo
*/
UserVo selectUserVoById(Integer id);
} }

View File

@ -12,6 +12,8 @@ public class UserDto extends SysUser {
*/ */
private Integer role; private Integer role;
private Integer deptId;
/** /**
* 新密码 * 新密码
*/ */
@ -32,4 +34,5 @@ public class UserDto extends SysUser {
public void setNewpassword1(String newpassword1) { public void setNewpassword1(String newpassword1) {
this.newpassword1 = newpassword1; this.newpassword1 = newpassword1;
} }
} }

View File

@ -62,6 +62,11 @@ public class SysUser extends Model<SysUser> {
*/ */
private String avatar; private String avatar;
/**
* 部门ID
*/
@TableField("dept_id")
private Integer deptId;
public Integer getUserId() { public Integer getUserId() {
@ -141,16 +146,27 @@ public class SysUser extends Model<SysUser> {
this.avatar = avatar; this.avatar = avatar;
} }
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Override @Override
public String toString() { public String toString() {
return "SysUser{" + return "SysUser{" +
", userId=" + userId + "userId=" + userId +
", username=" + username + ", username='" + username + '\'' +
", password=" + password + ", password='" + password + '\'' +
", salt=" + salt + ", salt='" + salt + '\'' +
", createTime=" + createTime + ", createTime=" + createTime +
", updateTime=" + updateTime + ", updateTime=" + updateTime +
", delFlag=" + delFlag + ", delFlag='" + delFlag + '\'' +
"}"; ", introduction='" + introduction + '\'' +
", avatar='" + avatar + '\'' +
", deptId=" + deptId +
'}';
} }
} }

View File

@ -20,5 +20,5 @@ public interface SysLogService extends IService<SysLog> {
* @param id 日志ID * @param id 日志ID
* @return true/false * @return true/false
*/ */
Boolean updateByLogId(Integer id); Boolean updateByLogId(Long id);
} }

View File

@ -7,6 +7,8 @@ import com.github.pig.admin.model.dto.RoleDto;
import com.github.pig.admin.model.entity.SysRole; import com.github.pig.admin.model.entity.SysRole;
import com.github.pig.common.util.Query; import com.github.pig.common.util.Query;
import java.util.List;
/** /**
* <p> * <p>
* 服务类 * 服务类
@ -40,4 +42,11 @@ public interface SysRoleService extends IService<SysRole> {
* @return 成功失败 * @return 成功失败
*/ */
Boolean updateRoleById(RoleDto roleDto); Boolean updateRoleById(RoleDto roleDto);
/**
* 通过部门ID查询角色列表
* @param deptId 部门ID
* @return 角色列表
*/
List<SysRole> selectListByDeptId(Integer deptId);
} }

View File

@ -86,4 +86,11 @@ public interface SysUserService extends IService<SysUser> {
* @return 用户信息 * @return 用户信息
*/ */
UserVo findUserByOpenId(String openId); UserVo findUserByOpenId(String openId);
/**
* 通过ID查询用户信息
* @param id 用户ID
* @return 用户信息
*/
UserVo selectUserVoById(Integer id);
} }

View File

@ -23,7 +23,7 @@ import java.util.Date;
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService { public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
@Override @Override
public Boolean updateByLogId(Integer id) { public Boolean updateByLogId(Long id) {
Assert.isNull(id, "日志ID为空"); Assert.isNull(id, "日志ID为空");
SysLog sysLog = new SysLog(); SysLog sysLog = new SysLog();

View File

@ -15,6 +15,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/** /**
* <p> * <p>
* 服务实现类 * 服务实现类
@ -67,7 +69,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
* @param roleDto 含有部门信息 * @param roleDto 含有部门信息
* @return 成功失败 * @return 成功失败
*/ */
@Transactional @Transactional(rollbackFor = Exception.class)
@Override @Override
public Boolean updateRoleById(RoleDto roleDto) { public Boolean updateRoleById(RoleDto roleDto) {
//删除原有的角色部门关系 //删除原有的角色部门关系
@ -87,4 +89,15 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
sysRoleDeptMapper.insert(roleDept); sysRoleDeptMapper.insert(roleDept);
return true; return true;
} }
/**
* 通过部门ID查询角色列表
*
* @param deptId 部门ID
* @return 角色列表
*/
@Override
public List<SysRole> selectListByDeptId(Integer deptId) {
return sysRoleMapper.selectListByDeptId(deptId);
}
} }

View File

@ -18,7 +18,9 @@ import com.github.pig.common.util.Query;
import com.github.pig.common.util.template.MobileMsgTemplate; import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.common.vo.SysRole; import com.github.pig.common.vo.SysRole;
import com.github.pig.common.vo.UserVo; import com.github.pig.common.vo.UserVo;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.RandomUtil; import com.xiaoleilu.hutool.util.RandomUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -66,8 +68,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
//设置角色列表 //设置角色列表
List<SysRole> roleList = userVo.getRoleList(); List<SysRole> roleList = userVo.getRoleList();
List<String> roleNames = new ArrayList<>(); List<String> roleNames = new ArrayList<>();
for (SysRole sysRole : roleList) { if (CollectionUtil.isNotEmpty(roleList)) {
roleNames.add(sysRole.getRoleName()); for (SysRole sysRole : roleList) {
if (!StrUtil.equals(SecurityConstants.BASE_ROLE, sysRole.getRoleName())) {
roleNames.add(sysRole.getRoleName());
}
}
} }
String[] roles = roleNames.toArray(new String[roleNames.size()]); String[] roles = roleNames.toArray(new String[roleNames.size()]);
userInfo.setRoles(roles); userInfo.setRoles(roles);
@ -113,6 +119,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
return query; return query;
} }
/**
* 通过ID查询用户信息
*
* @param id 用户ID
* @return 用户信息
*/
@Override
public UserVo selectUserVoById(Integer id) {
return sysUserMapper.selectUserVoById(id);
}
/** /**
* 保存用户验证码和randomStr绑定 * 保存用户验证码和randomStr绑定
* *
@ -142,7 +159,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
if (tempCode == null) { if (tempCode == null) {
String code = RandomUtil.randomNumbers(4); String code = RandomUtil.randomNumbers(4);
logger.info("短信发送请求消息中心 -> 手机号:{} -> 验证码:{}", mobile, code); logger.info("短信发送请求消息中心 -> 手机号:{} -> 验证码:{}", mobile, code);
rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE,new MobileMsgTemplate(mobile,code, CommonConstant.ALIYUN_SMS)); rabbitTemplate.convertAndSend(MqQueueConstant.MOBILE_CODE_QUEUE, new MobileMsgTemplate(mobile, code, CommonConstant.ALIYUN_SMS));
redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS); redisTemplate.opsForValue().set(SecurityConstants.DEFAULT_CODE_KEY + mobile, code, SecurityConstants.DEFAULT_IMAGE_EXPIRE, TimeUnit.SECONDS);
result = true; result = true;
} }

View File

@ -18,6 +18,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -36,4 +36,16 @@
WHERE r.del_flag = 0 WHERE r.del_flag = 0
ORDER BY r.role_id ASC ORDER BY r.role_id ASC
</select> </select>
<select id="selectListByDeptId" resultMap="BaseResultMap">
SELECT
r.role_id,
r.role_name,
r.role_code,
r.role_desc,
r.create_time,
r.update_time,
r.del_flag
FROM sys_role r LEFT OUTER JOIN sys_role_dept rd ON rd.role_id = r.role_id
WHERE rd.dept_id = #{deptId}
</select>
</mapper> </mapper>

View File

@ -9,6 +9,7 @@
<result column="introduction" property="introduction" /> <result column="introduction" property="introduction" />
<result column="avatar" property="avatar" /> <result column="avatar" property="avatar" />
<result column="salt" property="salt"/> <result column="salt" property="salt"/>
<result column="dept_id" property="deptId"/>
<result column="create_time" property="createTime"/> <result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/> <result column="update_time" property="updateTime"/>
<result column="del_flag" property="delFlag"/> <result column="del_flag" property="delFlag"/>
@ -25,6 +26,8 @@
<result column="ucreate_time" property="createTime"/> <result column="ucreate_time" property="createTime"/>
<result column="uupdate_time" property="updateTime"/> <result column="uupdate_time" property="updateTime"/>
<result column="udel_flag" property="delFlag"/> <result column="udel_flag" property="delFlag"/>
<result column="deptId" property="deptId"/>
<result column="deptName" property="deptName"/>
<collection property="roleList" ofType="com.github.pig.common.vo.SysRole"> <collection property="roleList" ofType="com.github.pig.common.vo.SysRole">
<id column="role_id" property="roleId" /> <id column="role_id" property="roleId" />
<result column="role_name" property="roleName" /> <result column="role_name" property="roleName" />
@ -43,9 +46,11 @@
`user`.salt, `user`.salt,
`user`.introduction, `user`.introduction,
`user`.avatar, `user`.avatar,
`user`.dept_id,
`user`.create_time AS ucreate_time, `user`.create_time AS ucreate_time,
`user`.update_time AS uupdate_time, `user`.update_time AS uupdate_time,
`user`.del_flag AS udel_flag, `user`.del_flag AS udel_flag,
`user`.dept_id AS deptId,
r.role_id, r.role_id,
r.role_name, r.role_name,
r.role_code, r.role_code,
@ -73,6 +78,34 @@
WHERE `user`.salt = #{openId} WHERE `user`.salt = #{openId}
</select> </select>
<select id="selectUserVoById" resultMap="userVoResultMap">
SELECT
`user`.user_id,
`user`.username,
`user`.`password`,
`user`.salt,
`user`.introduction,
`user`.avatar,
`user`.create_time AS create_time,
`user`.update_time AS uupdate_time,
`user`.del_flag AS udel_flag,
r.role_id,
r.role_name,
r.role_code,
r.role_desc,
r.create_time AS rcreate_time,
r.update_time AS rupdate_time,
d.name AS deptName,
d.dept_id AS deptId
FROM
sys_user AS `user`
LEFT JOIN sys_user_role AS ur ON ur.user_id = `user`.user_id
LEFT JOIN sys_role AS r ON r.role_id = ur.role_id
LEFT JOIN sys_dept AS d ON d.dept_id = `user`.dept_id
WHERE
`user`.user_id = #{id}
</select>
<select id="selectUserVoPage" resultMap="userVoResultMap" > <select id="selectUserVoPage" resultMap="userVoResultMap" >
SELECT SELECT
`user`.user_id, `user`.user_id,
@ -89,11 +122,14 @@
r.role_code, r.role_code,
r.role_desc, r.role_desc,
r.create_time AS rcreate_time, r.create_time AS rcreate_time,
r.update_time AS rupdate_time r.update_time AS rupdate_time,
d.name AS deptName,
d.dept_id AS deptId
FROM FROM
sys_user AS `user` sys_user AS `user`
LEFT JOIN sys_user_role AS ur ON ur.user_id = `user`.user_id LEFT JOIN sys_user_role AS ur ON ur.user_id = `user`.user_id
LEFT JOIN sys_role AS r ON r.role_id = ur.role_id LEFT JOIN sys_role AS r ON r.role_id = ur.role_id
LEFT JOIN sys_dept AS d ON d.dept_id = `user`.dept_id
WHERE WHERE
r.del_flag = 0 r.del_flag = 0
<if test="username != null and username != ''"> <if test="username != null and username != ''">

View File

@ -1,4 +1,4 @@
import com.github.pig.admin.PigAdminApplication; package com.github.pig.admin;
import org.jasypt.encryption.StringEncryptor; import org.jasypt.encryption.StringEncryptor;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@ -20,7 +20,9 @@
</properties> </properties>
<modules> <modules>
<module>pig-daemon-service</module>
<module>pig-mc-service</module> <module>pig-mc-service</module>
<module>pig-sso-client-demo</module>
<module>pig-upms-service</module> <module>pig-upms-service</module>
</modules> </modules>

View File

@ -34,6 +34,10 @@
<artifactId>spring-boot-admin-server-ui</artifactId> <artifactId>spring-boot-admin-server-ui</artifactId>
<version>1.5.6</version> <version>1.5.6</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId> <artifactId>spring-cloud-starter-turbine</artifactId>

View File

@ -1,10 +1,20 @@
package com.github.pig.monitor; package com.github.pig.monitor;
import de.codecentric.boot.admin.config.EnableAdminServer; import de.codecentric.boot.admin.config.EnableAdminServer;
import de.codecentric.boot.admin.notify.LoggingNotifier;
import de.codecentric.boot.admin.notify.Notifier;
import de.codecentric.boot.admin.notify.RemindingNotifier;
import de.codecentric.boot.admin.notify.filter.FilteringNotifier;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.turbine.EnableTurbine; import org.springframework.cloud.netflix.turbine.EnableTurbine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.concurrent.TimeUnit;
/** /**
* @author lengleng * @author lengleng
@ -20,4 +30,30 @@ public class PigMonitorApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(PigMonitorApplication.class, args); SpringApplication.run(PigMonitorApplication.class, args);
} }
@Configuration
public static class NotifierConfig {
@Bean
@Primary
public RemindingNotifier remindingNotifier() {
RemindingNotifier notifier = new RemindingNotifier(filteringNotifier(loggerNotifier()));
notifier.setReminderPeriod(TimeUnit.SECONDS.toMillis(10));
return notifier;
}
@Scheduled(fixedRate = 1_000L)
public void remind() {
remindingNotifier().sendReminders();
}
@Bean
public FilteringNotifier filteringNotifier(Notifier delegate) {
return new FilteringNotifier(delegate);
}
@Bean
public LoggingNotifier loggerNotifier() {
return new LoggingNotifier();
}
}
} }

View File

@ -0,0 +1,28 @@
package com.github.pig.monitor.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* @author lengleng
* @date 2018/1/25
* 监控短信接收者列表
*/
@Configuration
@ConditionalOnExpression("!'${mobiles}'.isEmpty()")
@ConfigurationProperties(prefix = "mobiles")
public class MonitorMobilePropertiesConfig {
private List<String> users = new ArrayList<>();
public List<String> getUsers() {
return users;
}
public void setUsers(List<String> users) {
this.users = users;
}
}

View File

@ -0,0 +1,44 @@
package com.github.pig.monitor.config;
import com.github.pig.monitor.filter.MobileNotifier;
import de.codecentric.boot.admin.notify.RemindingNotifier;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.concurrent.TimeUnit;
/**
* @author lengleng
* @date 2018/1/25
* 监控提醒配置
*/
@Configuration
@EnableScheduling
public class PigNotifierConfiguration {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private MonitorMobilePropertiesConfig monitorMobilePropertiesConfig;
@Bean
@Primary
public RemindingNotifier remindingNotifier() {
RemindingNotifier remindingNotifier = new RemindingNotifier(mobileNotifier());
remindingNotifier.setReminderPeriod(TimeUnit.MINUTES.toMillis(1));
return remindingNotifier;
}
@Bean
public MobileNotifier mobileNotifier(){
return new MobileNotifier(monitorMobilePropertiesConfig,rabbitTemplate);
}
@Scheduled(fixedRate = 60_000L)
public void remind() {
remindingNotifier().sendReminders();
}
}

View File

@ -0,0 +1,70 @@
package com.github.pig.monitor.filter;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.constant.MqQueueConstant;
import com.github.pig.common.constant.enums.EnumSmsChannel;
import com.github.pig.common.util.template.MobileMsgTemplate;
import com.github.pig.monitor.config.MonitorMobilePropertiesConfig;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.CollectionUtil;
import de.codecentric.boot.admin.event.ClientApplicationEvent;
import de.codecentric.boot.admin.event.ClientApplicationStatusChangedEvent;
import de.codecentric.boot.admin.notify.AbstractStatusChangeNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
/**
* @author lengleng
* @date 2018/1/25
* 服务下线手机短信通知
*/
@Slf4j
public class MobileNotifier extends AbstractStatusChangeNotifier {
public static final String STATUS_CHANGE = "STATUS_CHANGE";
private RabbitTemplate rabbitTemplate;
private MonitorMobilePropertiesConfig monitorMobilePropertiesConfig;
public MobileNotifier(MonitorMobilePropertiesConfig monitorMobilePropertiesConfig, RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
this.monitorMobilePropertiesConfig = monitorMobilePropertiesConfig;
}
/**
* 判断是否通知
*
* @param event 事件
* @return
*/
@Override
protected boolean shouldNotify(ClientApplicationEvent event) {
boolean shouldNotify = false;
if (STATUS_CHANGE.equals(event.getType())
&& event.getApplication().getStatusInfo().isOffline()
|| event.getApplication().getStatusInfo().isDown()) {
shouldNotify = true;
}
return shouldNotify;
}
/**
* 通知逻辑
*
* @param event 事件
* @throws Exception 异常
*/
@Override
protected void doNotify(ClientApplicationEvent event) {
if (event instanceof ClientApplicationStatusChangedEvent) {
log.info("Application {} ({}) is {}", event.getApplication().getName(),
event.getApplication().getId(), ((ClientApplicationStatusChangedEvent) event).getTo().getStatus());
String text = String.format("应用:%s 服务ID:%s 下线,时间:%s", event.getApplication().getName(), event.getApplication().getId(), DateUtil.date(event.getTimestamp()).toString());
rabbitTemplate.convertAndSend(MqQueueConstant.SERVICE_STATUS_CHANGE,
new MobileMsgTemplate(CollectionUtil.join(monitorMobilePropertiesConfig.getUsers(), ","),
text, EnumSmsChannel.ALIYUN.getName()));
} else {
log.info("Application {} ({}) {}", event.getApplication().getName(),
event.getApplication().getId(), event.getType());
}
}
}

View File

@ -17,6 +17,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -0,0 +1,65 @@
<?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>
<groupId>com.github.pig</groupId>
<artifactId>pig-zipkin-db</artifactId>
<version>${pig.version}</version>
<packaging>jar</packaging>
<name>pig-zipkin-db</name>
<description>zipkin监控模块</description>
<parent>
<groupId>com.github.pig</groupId>
<artifactId>pig-visual</artifactId>
<version>${pig.version}</version>
</parent>
<dependencies>
<dependency>
<groupId>com.github.pig</groupId>
<artifactId>pig-common</artifactId>
<version>${pig.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<!-- 使用消息的方式收集数据使用rabbitmq -->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-mysql</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
package com.github.pig.zipkin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import zipkin.server.EnableZipkinServer;
/**
* @author lengleng
* @date 2018-01-24
* zipkin mysql 存储实现
*/
@EnableDiscoveryClient
@SpringBootApplication
@EnableZipkinServer
public class PigZipkinDbApplication {
public static void main(String[] args) {
SpringApplication.run(PigZipkinDbApplication.class, args);
}
}

View File

@ -0,0 +1,35 @@
spring:
application:
name: pig-zipkin-db
profiles:
active: dev
cloud:
config:
fail-fast: true
discovery:
service-id: pig-config-server
enabled: true
profile: ${spring.profiles.active}
label: ${spring.profiles.active}
---
spring:
profiles: dev
eureka:
instance:
prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client:
serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka
---
spring:
profiles: prd
eureka:
instance:
prefer-ip-address: true
client:
serviceUrl:
defaultZone: http://pig:gip6666@pig-eureka:1025/eureka

View File

@ -25,20 +25,22 @@
</dependency> </dependency>
<!--zipkin--> <!--zipkin-->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>io.zipkin.java</groupId>
<artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
<version>2.3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.zipkin.java</groupId> <groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId> <artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>io.zipkin.java</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId> <artifactId>zipkin-server</artifactId>
</dependency> </dependency>
<!-- 使用消息的方式收集数据使用rabbitmq -->
<dependency> <dependency>
<groupId>io.zipkin.java</groupId> <groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId> <artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId>
<version>2.3.1</version> <version>2.3.1</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -3,7 +3,7 @@ package com.github.pig.zipkin;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer; import zipkin.server.EnableZipkinServer;
/** /**
* @author lengleng * @author lengleng
@ -12,7 +12,7 @@ import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer;
*/ */
@EnableDiscoveryClient @EnableDiscoveryClient
@SpringBootApplication @SpringBootApplication
@EnableZipkinStreamServer @EnableZipkinServer
public class PigZipkinElkApplication { public class PigZipkinElkApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -18,6 +18,8 @@ spring:
eureka: eureka:
instance: instance:
prefer-ip-address: true prefer-ip-address: true
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 20
client: client:
serviceUrl: serviceUrl:
defaultZone: http://pig:gip6666@localhost:1025/eureka defaultZone: http://pig:gip6666@localhost:1025/eureka

View File

@ -19,6 +19,7 @@
<modules> <modules>
<module>pig-monitor</module> <module>pig-monitor</module>
<module>pig-zipkin-elk</module> <module>pig-zipkin-elk</module>
<module>pig-zipkin-db</module>
<!--<module>pig-cache-cloud</module>--> <!--<module>pig-cache-cloud</module>-->
</modules> </modules>
</project> </project>

45
pom.xml
View File

@ -9,6 +9,13 @@
<version>${pig.version}</version> <version>${pig.version}</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@ -72,13 +79,6 @@
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId> <artifactId>spring-cloud-dependencies</artifactId>
@ -105,39 +105,16 @@
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.3.0.603</version>
</plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
</build> </build>
<!-- 使用aliyun镜像 -->
<repositories> <repositories>
<repository> <repository>
<id>nexus</id> <id>aliyun</id>
<name>nexus Repository</name> <name>aliyun</name>
<url>http://106.14.69.75:8081/repository/maven-releases/</url> <url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository> </repository>
</repositories> </repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>nexus PluginRepository</name>
<url>http://106.14.69.75:8081/repository/maven-releases/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project> </project>