isLogin();
35 | }
36 |
--------------------------------------------------------------------------------
/live-auth/src/main/java/com/easy/live/streaming/auth/service/impl/AuthServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.auth.service.impl;
2 |
3 | import com.easy.live.streaming.auth.service.AuthService;
4 | import com.easy.live.streaming.common.config.Constants;
5 | import com.easy.live.streaming.data.bean.BaseOutput;
6 | import com.easy.live.streaming.data.cache.SimpleCacheService;
7 | import com.easy.live.streaming.data.cache.ThreadLocalUserCache;
8 | import com.easy.live.streaming.data.cache.UserCache;
9 | import com.easy.live.streaming.data.entity.user.LiveUser;
10 | import com.easy.live.streaming.data.service.user.LiveUserService;
11 | import com.easy.live.streaming.servants.protocol.input.user.UserInput;
12 | import org.apache.shiro.SecurityUtils;
13 | import org.apache.shiro.authc.AuthenticationException;
14 | import org.apache.shiro.authc.UsernamePasswordToken;
15 | import org.apache.shiro.subject.Subject;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.stereotype.Service;
18 |
19 | /**
20 | * Description: 鉴权Service实现
21 | * Author: zhangliangfu
22 | * Create on: 2019-08-14 14:49
23 | */
24 | @Service
25 | public class AuthServiceImpl implements AuthService {
26 |
27 | @Autowired
28 | private SimpleCacheService simpleCacheService;
29 | @Autowired
30 | private LiveUserService userService;
31 |
32 | /**
33 | * 用户登录
34 | *
35 | * @param input
36 | * @return
37 | */
38 | @Override
39 | public BaseOutput login(UserInput input) {
40 | UsernamePasswordToken upt = new UsernamePasswordToken(input.getName(), input.getPassword());
41 | Subject subject = SecurityUtils.getSubject();
42 | try {
43 | subject.login(upt);
44 | String sessionId = ThreadLocalUserCache.getUserCache().getSessionId();
45 | UserCache userCache = new UserCache();
46 | LiveUser user = userService.findLiveUserByName(input.getName());
47 | userCache.setUserId(user.getId());
48 | simpleCacheService.add(Constants.LOGIN_CACHE+sessionId, userCache, Constants.LOGIN_CACHE_TIME);
49 | } catch (AuthenticationException e) {
50 | e.printStackTrace();
51 | return new BaseOutput(Constants.RetMsg.FAIL.code,"用户名或密码不正确!");
52 | }
53 | return new BaseOutput(Constants.RetMsg.SUCCESS.code,"登录成功!");
54 | }
55 |
56 | /**
57 | * 用户登出
58 | *
59 | * @return
60 | */
61 | @Override
62 | public BaseOutput logout() {
63 | Subject subject = SecurityUtils.getSubject();
64 | try {
65 | subject.logout();
66 | String sessionId = ThreadLocalUserCache.getUserCache().getSessionId();
67 | simpleCacheService.del(Constants.LOGIN_CACHE+sessionId);
68 | } catch (AuthenticationException e) {
69 | e.printStackTrace();
70 | return new BaseOutput(Constants.RetMsg.FAIL.code,"登出失败!");
71 | }
72 | return new BaseOutput(Constants.RetMsg.SUCCESS.code,"登出成功!");
73 | }
74 |
75 | /**
76 | * 用户登出
77 | *
78 | * @return
79 | */
80 | @Override
81 | public BaseOutput isLogin() {
82 | Subject subject = SecurityUtils.getSubject();
83 | boolean authenticated = subject.isAuthenticated();
84 | if (authenticated){
85 | String sessionId = subject.getSession().getId().toString();
86 | UserCache userCache = simpleCacheService.get(sessionId, UserCache.class);
87 | return new BaseOutput(Constants.RetMsg.LOGIN_YES.code, Constants.RetMsg.LOGIN_YES.msg, userCache);
88 | }else {
89 | return new BaseOutput(Constants.RetMsg.LOGIN_NO.code, Constants.RetMsg.LOGIN_NO.msg);
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/live-auth/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: auth-server
4 |
5 | server:
6 | port: 8010
--------------------------------------------------------------------------------
/live-auth/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ____ ___ ___
2 | /\ _`\ /\_ \ __ /'___\
3 | \ \ \L\_\ __ ____ __ __ \//\ \ /\_\/\ \__/ __
4 | \ \ _\L /'__`\ /',__\/\ \/\ \ \ \ \ \/\ \ \ ,__\/'__`\
5 | \ \ \L\ \/\ \L\.\_/\__, `\ \ \_\ \ \_\ \_\ \ \ \ \_/\ __/
6 | \ \____/\ \__/.\_\/\____/\/`____ \ /\____\\ \_\ \_\\ \____\
7 | \/___/ \/__/\/_/\/___/ `/___/> \ \/____/ \/_/\/_/ \/____/
8 | /\___/
9 | \/__/
--------------------------------------------------------------------------------
/live-auth/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | easy:
2 | eurekaServer: http://live.registry.com:8001/eureka/
3 |
4 | eureka:
5 | instance:
6 | lease-expiration-duration-in-seconds: 15
7 | lease-renewal-interval-in-seconds: 5
8 | preferIpAddress: true
9 | hostname: live.registry.com
10 | metadataMap:
11 | cluster: MAIN
12 | client:
13 | registryFetchIntervalSeconds: 5
14 | serviceUrl:
15 | defaultZone: ${easy.eurekaServer}
16 |
17 | spring:
18 | cloud:
19 | config:
20 | profile: dev
21 | discovery:
22 | enabled: true
23 | serviceId: config-server
24 |
25 |
26 |
--------------------------------------------------------------------------------
/live-auth/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | ${FILE_LOG_PATTERN}
13 | UTF-8
14 |
15 |
16 |
17 | ${LOG_HOME}/gateway-server-%d{yyyy-MM-dd}.%i.log
18 |
19 | 20MB
20 | 60
21 | 20GB
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/live-common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | live-parent
7 | com.easy
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | com.easy
13 | live-common
14 |
15 |
16 |
17 |
18 | org.projectlombok
19 | lombok
20 |
21 |
22 | org.slf4j
23 | slf4j-api
24 |
25 |
26 | org.apache.shiro
27 | shiro-core
28 |
29 |
30 | com.google.guava
31 | guava
32 |
33 |
34 | org.springframework.data
35 | spring-data-redis
36 |
37 |
38 | org.springframework.session
39 | spring-session
40 |
41 |
42 | redis.clients
43 | jedis
44 |
45 |
46 | org.apache.commons
47 | commons-lang3
48 |
49 |
50 | org.springframework.boot
51 | spring-boot-starter-data-jpa
52 |
53 |
54 | org.apache.tomcat.embed
55 | tomcat-embed-core
56 |
57 |
58 | commons-codec
59 | commons-codec
60 |
61 |
62 | org.apache.httpcomponents
63 | httpcore
64 |
65 |
66 | org.apache.httpcomponents
67 | httpclient
68 |
69 |
70 | com.aliyun.oss
71 | aliyun-sdk-oss
72 |
73 |
74 | org.springframework
75 | spring-webmvc
76 |
77 |
78 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/config/Constants.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.config;
2 |
3 | /**
4 | * Created by ZLF on 2017/6/21.
5 | */
6 | public class Constants {
7 |
8 | public static final String LIVE_URL_PREFIX = "rtmp://192.168.10.110:1935/live/room";
9 |
10 | public static final String LOGIN_CACHE = "LOGIN_CACHE_";
11 | public static final int LOGIN_CACHE_TIME = 600; //十分钟
12 |
13 | public enum RetMsg{
14 | SUCCESS(200, "操作成功"),
15 |
16 | FAIL(500, "操作失败"),
17 | LOGIN_YES(401, "已登录"),
18 | LOGIN_NO(402, "未登录"),
19 |
20 | EXCEPTION_LOGIN(301, "未登录异常");
21 |
22 | public Integer code;
23 |
24 | public String msg;
25 |
26 | RetMsg(Integer retCode, String retMsg) {
27 | this.code = retCode;
28 | this.msg = retMsg;
29 | }
30 |
31 | public Integer getCode() {
32 | return code;
33 | }
34 |
35 | public String getMsg() {
36 | return msg;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/exception/Exceptions.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.exception;
2 | import java.io.StringWriter;
3 |
4 | /**
5 | * 关于异常的工具类.
6 | *
7 | */
8 | public class Exceptions
9 | {
10 |
11 | private Exceptions()
12 | {
13 | super();
14 | }
15 |
16 | /**
17 | * 将CheckedException转换为UncheckedException.
18 | */
19 | public static RuntimeException unchecked(Exception e)
20 | {
21 | if (e instanceof RuntimeException)
22 | {
23 | return (RuntimeException)e;
24 | }
25 | else
26 | {
27 | return new RuntimeException(e);
28 | }
29 | }
30 |
31 | /**
32 | * 将ErrorStack转化为String.
33 | */
34 | public static String getStackTraceAsString(Exception e)
35 | {
36 | StringWriter stringWriter = new StringWriter();
37 | return stringWriter.toString();
38 | }
39 |
40 | /**
41 | * 判断异常是否由某些底层的异常引起.
42 | */
43 | public static boolean isCausedBy(Exception ex, Class extends Exception>... causeExceptionClasses)
44 | {
45 | Throwable cause = ex;
46 | while (cause != null)
47 | {
48 | for (Class extends Exception> causeClass : causeExceptionClasses)
49 | {
50 | if (causeClass.isInstance(cause))
51 | {
52 | return true;
53 | }
54 | }
55 | cause = cause.getCause();
56 | }
57 | return false;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/exception/GlobalException.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.exception;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * Description: 全局异常
8 | * Author: zhangliangfu
9 | * Create on: 2019-08-01 14:57
10 | */
11 | @Getter
12 | @Setter
13 | public class GlobalException extends Exception {
14 | private Integer code;
15 | private String message;
16 |
17 | public GlobalException(Integer code, String message){
18 | this.code = code;
19 | this.message = message;
20 | }
21 |
22 | @Override
23 | public String getMessage(){
24 | return message;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/Digests.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2005-2014 leelong.cn
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | */
6 | package com.easy.live.streaming.common.util;
7 | import com.easy.live.streaming.common.exception.Exceptions;
8 | import org.apache.commons.lang3.Validate;
9 |
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.security.GeneralSecurityException;
13 | import java.security.MessageDigest;
14 | import java.security.SecureRandom;
15 |
16 | /**
17 | * 支持SHA-1/MD5消息摘要的工具类.
18 | *
19 | * 返回ByteSource,可进一步被编码为Hex, Base64或UrlSafeBase64
20 | *
21 | */
22 | public class Digests
23 | {
24 |
25 | private static final String SHA1 = "SHA-1";
26 |
27 | private static final String MD5 = "MD5";
28 |
29 | private static SecureRandom random = new SecureRandom();
30 |
31 | /**
32 | * 对输入字符串进行sha1散列.
33 | */
34 | public static byte[] sha1(byte[] input)
35 | {
36 | return digest(input, SHA1, null, 1);
37 | }
38 |
39 | public static byte[] sha1(byte[] input, byte[] salt)
40 | {
41 | return digest(input, SHA1, salt, 1);
42 | }
43 |
44 | public static byte[] sha1(byte[] input, byte[] salt, int iterations)
45 | {
46 | return digest(input, SHA1, salt, iterations);
47 | }
48 |
49 | /**
50 | * 对字符串进行散列, 支持md5与sha1算法.
51 | */
52 | private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations)
53 | {
54 | try
55 | {
56 | MessageDigest digest = MessageDigest.getInstance(algorithm);
57 |
58 | if (salt != null)
59 | {
60 | digest.update(salt);
61 | }
62 |
63 | byte[] result = digest.digest(input);
64 |
65 | for (int i = 1; i < iterations; i++)
66 | {
67 | digest.reset();
68 | result = digest.digest(result);
69 | }
70 | return result;
71 | }
72 | catch (GeneralSecurityException e)
73 | {
74 | throw Exceptions.unchecked(e);
75 | }
76 | }
77 |
78 | /**
79 | * 生成随机的Byte[]作为salt.
80 | *
81 | * @param numBytes byte数组的大小
82 | */
83 | public static byte[] generateSalt(int numBytes)
84 | {
85 | Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", numBytes);
86 |
87 | byte[] bytes = new byte[numBytes];
88 | random.nextBytes(bytes);
89 | return bytes;
90 | }
91 |
92 | /**
93 | * 对文件进行md5散列.
94 | */
95 | public static byte[] md5(InputStream input)
96 | throws IOException
97 | {
98 | return digest(input, MD5);
99 | }
100 |
101 | /**
102 | * 对文件进行sha1散列.
103 | */
104 | public static byte[] sha1(InputStream input)
105 | throws IOException
106 | {
107 | return digest(input, SHA1);
108 | }
109 |
110 | private static byte[] digest(InputStream input, String algorithm)
111 | throws IOException
112 | {
113 | try
114 | {
115 | MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
116 | int bufferLength = 8 * 1024;
117 | byte[] buffer = new byte[bufferLength];
118 | int read = input.read(buffer, 0, bufferLength);
119 |
120 | while (read > -1)
121 | {
122 | messageDigest.update(buffer, 0, read);
123 | read = input.read(buffer, 0, bufferLength);
124 | }
125 |
126 | return messageDigest.digest();
127 | }
128 | catch (GeneralSecurityException e)
129 | {
130 | throw Exceptions.unchecked(e);
131 | }
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/Encodes.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2005-2014 leelong.cn
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | */
6 | package com.easy.live.streaming.common.util;
7 | import com.easy.live.streaming.common.exception.Exceptions;
8 | import org.apache.commons.codec.DecoderException;
9 | import org.apache.commons.codec.binary.Base64;
10 | import org.apache.commons.codec.binary.Hex;
11 | import org.apache.commons.lang3.StringEscapeUtils;
12 |
13 | import java.io.UnsupportedEncodingException;
14 | import java.net.URLDecoder;
15 | import java.net.URLEncoder;
16 |
17 | /**
18 | * 封装各种格式的编码解码工具类.
19 | *
20 | * 1.Commons-Codec的 hex/base64 编码
21 | * 2.自制的base62 编码
22 | * 3.Commons-Lang的xml/html escape
23 | * 4.JDK提供的URLEncoder
24 | *
25 | */
26 | public class Encodes {
27 |
28 | private static final String DEFAULT_URL_ENCODING = "UTF-8";
29 | private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
30 |
31 | /**
32 | * Hex编码.
33 | */
34 | public static String encodeHex(byte[] input) {
35 | return Hex.encodeHexString(input);
36 | }
37 |
38 | /**
39 | * Hex解码.
40 | */
41 | public static byte[] decodeHex(String input) {
42 | try {
43 | return Hex.decodeHex(input.toCharArray());
44 | } catch (DecoderException e) {
45 | throw Exceptions.unchecked(e);
46 | }
47 | }
48 |
49 | /**
50 | * Base64编码.
51 | */
52 | public static String encodeBase64(byte[] input) {
53 | return Base64.encodeBase64String(input);
54 | }
55 |
56 | /**
57 | * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548).
58 | */
59 | public static String encodeUrlSafeBase64(byte[] input) {
60 | return Base64.encodeBase64URLSafeString(input);
61 | }
62 |
63 | /**
64 | * Base64解码.
65 | */
66 | public static byte[] decodeBase64(String input) {
67 | return Base64.decodeBase64(input);
68 | }
69 |
70 | /**
71 | * Base62编码。
72 | */
73 | public static String encodeBase62(byte[] input) {
74 | char[] chars = new char[input.length];
75 | for (int i = 0; i < input.length; i++) {
76 | chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)];
77 | }
78 | return new String(chars);
79 | }
80 |
81 | /**
82 | * Html 转码.
83 | */
84 | public static String escapeHtml(String html) {
85 | return StringEscapeUtils.escapeHtml4(html);
86 | }
87 |
88 | /**
89 | * Html 解码.
90 | */
91 | public static String unescapeHtml(String htmlEscaped) {
92 | return StringEscapeUtils.unescapeHtml4(htmlEscaped);
93 | }
94 |
95 | /**
96 | * Xml 转码.
97 | */
98 | public static String escapeXml(String xml) {
99 | return StringEscapeUtils.escapeXml(xml);
100 | }
101 |
102 | /**
103 | * Xml 解码.
104 | */
105 | public static String unescapeXml(String xmlEscaped) {
106 | return StringEscapeUtils.unescapeXml(xmlEscaped);
107 | }
108 |
109 | /**
110 | * URL 编码, Encode默认为UTF-8.
111 | */
112 | public static String urlEncode(String part) {
113 | try {
114 | return URLEncoder.encode(part, DEFAULT_URL_ENCODING);
115 | } catch (UnsupportedEncodingException e) {
116 | throw Exceptions.unchecked(e);
117 | }
118 | }
119 |
120 | /**
121 | * URL 解码, Encode默认为UTF-8.
122 | */
123 | public static String urlDecode(String part) {
124 |
125 | try {
126 | return URLDecoder.decode(part, DEFAULT_URL_ENCODING);
127 | } catch (UnsupportedEncodingException e) {
128 | throw Exceptions.unchecked(e);
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/Servlets.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2005-2014 leelong.cn
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | */
6 | package com.easy.live.streaming.common.util;
7 |
8 | import com.google.common.net.HttpHeaders;
9 | import org.apache.commons.lang3.Validate;
10 |
11 | import javax.servlet.ServletRequest;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 | import java.io.UnsupportedEncodingException;
15 | import java.util.*;
16 | import java.util.Map.Entry;
17 |
18 | /**
19 | * Http与Servlet工具类.
20 | *
21 | */
22 | public class Servlets
23 | {
24 |
25 | // -- 常用数值定义 --//
26 | public static final long ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;
27 | private static final String DATE_END_WITH = "_DATE";
28 |
29 | /**
30 | * 设置客户端缓存过期时间 的Header.
31 | */
32 | public static void setExpiresHeader(HttpServletResponse response, long expiresSeconds)
33 | {
34 | // Http 1.0 header, set a fix expires date.
35 | response.setDateHeader(HttpHeaders.EXPIRES, System.currentTimeMillis()
36 | + (expiresSeconds * 1000));
37 | // Http 1.1 header, set a time after now.
38 | response.setHeader(HttpHeaders.CACHE_CONTROL, "private, max-age=" + expiresSeconds);
39 | }
40 |
41 | /**
42 | * 设置禁止客户端缓存的Header.
43 | */
44 | public static void setNoCacheHeader(HttpServletResponse response)
45 | {
46 | // Http 1.0 header
47 | response.setDateHeader(HttpHeaders.EXPIRES, 1L);
48 | response.addHeader(HttpHeaders.PRAGMA, "no-cache");
49 | // Http 1.1 header
50 | response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0");
51 | }
52 |
53 | /**
54 | * 设置LastModified Header.
55 | */
56 | public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedDate)
57 | {
58 | response.setDateHeader(HttpHeaders.LAST_MODIFIED, lastModifiedDate);
59 | }
60 |
61 | /**
62 | * 设置Etag Header.
63 | */
64 | public static void setEtag(HttpServletResponse response, String etag)
65 | {
66 | response.setHeader(HttpHeaders.ETAG, etag);
67 | }
68 |
69 | /**
70 | * 根据浏览器If-Modified-Since Header, 计算文件是否已被修改.
71 | *
72 | * 如果无修改, checkIfModify返回false ,设置304 not modify status.
73 | *
74 | * @param lastModified
75 | * 内容的最后修改时间.
76 | */
77 | public static boolean checkIfModifiedSince(HttpServletRequest request,
78 | HttpServletResponse response, long lastModified)
79 | {
80 | long ifModifiedSince = request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE);
81 | if ((ifModifiedSince != -1) && (lastModified < (ifModifiedSince + 1000)))
82 | {
83 | response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
84 | return false;
85 | }
86 | return true;
87 | }
88 |
89 | /**
90 | * 根据浏览器 If-None-Match Header, 计算Etag是否已无效.
91 | *
92 | * 如果Etag有效, checkIfNoneMatch返回false, 设置304 not modify status.
93 | *
94 | * @param etag
95 | * 内容的ETag.
96 | */
97 | public static boolean checkIfNoneMatchEtag(HttpServletRequest request,
98 | HttpServletResponse response, String etag)
99 | {
100 | String headerValue = request.getHeader(HttpHeaders.IF_NONE_MATCH);
101 | if (headerValue != null)
102 | {
103 | boolean conditionSatisfied = false;
104 | if (!"*".equals(headerValue))
105 | {
106 | StringTokenizer commaTokenizer = new StringTokenizer(headerValue, ",");
107 |
108 | while (!conditionSatisfied && commaTokenizer.hasMoreTokens())
109 | {
110 | String currentToken = commaTokenizer.nextToken();
111 | if (currentToken.trim().equals(etag))
112 | {
113 | conditionSatisfied = true;
114 | }
115 | }
116 | }
117 | else
118 | {
119 | conditionSatisfied = true;
120 | }
121 |
122 | if (conditionSatisfied)
123 | {
124 | response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
125 | response.setHeader(HttpHeaders.ETAG, etag);
126 | return false;
127 | }
128 | }
129 | return true;
130 | }
131 |
132 | /**
133 | * 设置让浏览器弹出下载对话框的Header.
134 | *
135 | * @param fileName
136 | * 下载后的文件名.
137 | */
138 | public static void setFileDownloadHeader(HttpServletResponse response, String fileName)
139 | {
140 | try
141 | {
142 | // 中文文件名支持
143 | String encodedfileName = new String(fileName.getBytes(), "ISO8859-1");
144 | response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""
145 | + encodedfileName + "\"");
146 | }
147 | catch (UnsupportedEncodingException e)
148 | {
149 | }
150 | }
151 |
152 | /**
153 | * 取得带相同前缀的Request Parameters, copy from spring WebUtils.
154 | *
155 | * 返回的结果的Parameter名已去除前缀.
156 | */
157 | public static Map getParametersStartingWith(ServletRequest request,
158 | String prefix)
159 | {
160 | Validate.notNull(request, "Request must not be null");
161 | Enumeration paramNames = request.getParameterNames();
162 | Map params = new TreeMap();
163 | if (prefix == null)
164 | {
165 | prefix = "";
166 | }
167 | while ((paramNames != null) && paramNames.hasMoreElements())
168 | {
169 | String paramName = (String) paramNames.nextElement();
170 | if ("".equals(prefix) || paramName.startsWith(prefix))
171 | {
172 | String unprefixed = paramName.substring(prefix.length());
173 | String[] values = request.getParameterValues(paramName);
174 | if ((values == null) || (values.length == 0))
175 | {
176 | // Do nothing, no values found at all.
177 | }
178 | else if (values.length > 1)
179 | {
180 | params.put(unprefixed, values);
181 | }
182 | else if (unprefixed.endsWith(DATE_END_WITH))
183 | { // 如果搜索为时间转换成date类型
184 | unprefixed = unprefixed.replace(DATE_END_WITH, "");
185 | params.put(unprefixed, SysDate.getDate(values[0], "yyyy-MM-dd HH:mm"));
186 | }
187 | else
188 | {
189 | params.put(unprefixed, values[0]);
190 | }
191 | }
192 | }
193 | return params;
194 | }
195 |
196 | /**
197 | * 组合Parameters生成Query String的Parameter部分, 并在paramter name上加上prefix.
198 | *
199 | * @see #getParametersStartingWith
200 | */
201 | public static String encodeParameterStringWithPrefix(Map params, String prefix)
202 | {
203 | if ((params == null) || (params.size() == 0))
204 | {
205 | return "";
206 | }
207 |
208 | if (prefix == null)
209 | {
210 | prefix = "";
211 | }
212 |
213 | StringBuilder queryStringBuilder = new StringBuilder();
214 | Iterator> it = params.entrySet().iterator();
215 | while (it.hasNext())
216 | {
217 | Entry entry = it.next();
218 | queryStringBuilder.append(prefix).append(entry.getKey()).append('=')
219 | .append(entry.getValue());
220 | if (it.hasNext())
221 | {
222 | queryStringBuilder.append('&');
223 | }
224 | }
225 | return queryStringBuilder.toString();
226 | }
227 |
228 | /**
229 | * 客户端对Http Basic验证的 Header进行编码.
230 | */
231 | public static String encodeHttpBasic(String userName, String password)
232 | {
233 | String encode = userName + ":" + password;
234 | return "Basic " + Encodes.encodeBase64(encode.getBytes());
235 | }
236 |
237 | }
238 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/jpa/Collections3.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2005-2014 leelong.cn
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | */
6 | package com.easy.live.streaming.common.util.jpa;
7 |
8 | import com.easy.live.streaming.common.util.Reflections;
9 | import org.apache.commons.beanutils.PropertyUtils;
10 | import org.apache.commons.lang3.StringUtils;
11 |
12 | import java.util.*;
13 |
14 | /**
15 | * Collections工具集.
16 | *
17 | * 在JDK的Collections和Guava的Collections2后, 命名为Collections3.
18 | *
19 | * 函数主要由两部分组成,一是自反射提取元素的功能,二是源自Apache Commons Collection, 争取不用在项目里引入它。
20 | *
21 | */
22 | public class Collections3 {
23 |
24 | /**
25 | * 提取集合中的对象的两个属性(通过Getter函数), 组合成Map.
26 | *
27 | * @param collection 来源集合.
28 | * @param keyPropertyName 要提取为Map中的Key值的属性名.
29 | * @param valuePropertyName 要提取为Map中的Value值的属性名.
30 | */
31 | public static Map extractToMap(final Collection collection, final String keyPropertyName,
32 | final String valuePropertyName) {
33 | Map map = new HashMap(collection.size());
34 |
35 | try {
36 | for (Object obj : collection) {
37 | map.put(PropertyUtils.getProperty(obj, keyPropertyName),
38 | PropertyUtils.getProperty(obj, valuePropertyName));
39 | }
40 | } catch (Exception e) {
41 | throw Reflections.convertReflectionExceptionToUnchecked(e);
42 | }
43 |
44 | return map;
45 | }
46 |
47 | /**
48 | * 提取集合中的对象的一个属性(通过Getter函数), 组合成List.
49 | *
50 | * @param collection 来源集合.
51 | * @param propertyName 要提取的属性名.
52 | */
53 | public static List extractToList(final Collection collection, final String propertyName) {
54 | List list = new ArrayList(collection.size());
55 |
56 | try {
57 | for (Object obj : collection) {
58 | list.add(PropertyUtils.getProperty(obj, propertyName));
59 | }
60 | } catch (Exception e) {
61 | throw Reflections.convertReflectionExceptionToUnchecked(e);
62 | }
63 |
64 | return list;
65 | }
66 |
67 | /**
68 | * 提取集合中的对象的一个属性(通过Getter函数), 组合成由分割符分隔的字符串.
69 | *
70 | * @param collection 来源集合.
71 | * @param propertyName 要提取的属性名.
72 | * @param separator 分隔符.
73 | */
74 | public static String extractToString(final Collection collection, final String propertyName, final String separator) {
75 | List list = extractToList(collection, propertyName);
76 | return StringUtils.join(list, separator);
77 | }
78 |
79 | /**
80 | * 转换Collection所有元素(通过toString())为String, 中间以 separator分隔。
81 | */
82 | public static String convertToString(final Collection collection, final String separator) {
83 | return StringUtils.join(collection, separator);
84 | }
85 |
86 | /**
87 | * 转换Collection所有元素(通过toString())为String, 每个元素的前面加入prefix,后面加入postfix,如mymessage
。
88 | */
89 | public static String convertToString(final Collection collection, final String prefix, final String postfix) {
90 | StringBuilder builder = new StringBuilder();
91 | for (Object o : collection) {
92 | builder.append(prefix).append(o).append(postfix);
93 | }
94 | return builder.toString();
95 | }
96 |
97 | /**
98 | * 判断是否为空.
99 | */
100 | public static boolean isEmpty(Collection collection) {
101 | return ((collection == null) || collection.isEmpty());
102 | }
103 |
104 | /**
105 | * 判断是否为空.
106 | */
107 | public static boolean isNotEmpty(Collection collection) {
108 | return ((collection != null) && !(collection.isEmpty()));
109 | }
110 |
111 | /**
112 | * 取得Collection的第一个元素,如果collection为空返回null.
113 | */
114 | public static T getFirst(Collection collection) {
115 | if (isEmpty(collection)) {
116 | return null;
117 | }
118 |
119 | return collection.iterator().next();
120 | }
121 |
122 | /**
123 | * 获取Collection的最后一个元素 ,如果collection为空返回null.
124 | */
125 | public static T getLast(Collection collection) {
126 | if (isEmpty(collection)) {
127 | return null;
128 | }
129 |
130 | // 当类型为List时,直接取得最后一个元素 。
131 | if (collection instanceof List) {
132 | List list = (List) collection;
133 | return list.get(list.size() - 1);
134 | }
135 |
136 | // 其他类型通过iterator滚动到最后一个元素.
137 | Iterator iterator = collection.iterator();
138 | while (true) {
139 | T current = iterator.next();
140 | if (!iterator.hasNext()) {
141 | return current;
142 | }
143 | }
144 | }
145 |
146 | /**
147 | * 返回a+b的新List.
148 | */
149 | public static List union(final Collection a, final Collection b) {
150 | List result = new ArrayList(a);
151 | result.addAll(b);
152 | return result;
153 | }
154 |
155 | /**
156 | * 返回a-b的新List.
157 | */
158 | public static List subtract(final Collection a, final Collection b) {
159 | List list = new ArrayList(a);
160 | for (T element : b) {
161 | list.remove(element);
162 | }
163 |
164 | return list;
165 | }
166 |
167 | /**
168 | * 返回a与b的交集的新List.
169 | */
170 | public static List intersection(Collection a, Collection b) {
171 | List list = new ArrayList();
172 |
173 | for (T element : a) {
174 | if (b.contains(element)) {
175 | list.add(element);
176 | }
177 | }
178 | return list;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/jpa/DynamicSpecifications.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.util.jpa;
2 | import com.google.common.collect.Lists;
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.springframework.data.jpa.domain.Specification;
5 |
6 | import javax.persistence.criteria.*;
7 | import java.util.Collection;
8 | import java.util.List;
9 |
10 | public class DynamicSpecifications
11 | {
12 | public static Specification bySearchFilter(final Collection filters, final Class clazz)
13 | {
14 | return new Specification()
15 | {
16 |
17 | public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder builder)
18 | {
19 | if (Collections3.isNotEmpty(filters))
20 | {
21 |
22 | List predicates = Lists.newArrayList();
23 | for (SearchFilter filter : filters)
24 | {
25 | // nested path translate, 如Task的名为"user.name"的filedName,
26 | // 转换为Task.user.name属性
27 | String[] names = StringUtils.split(filter.fieldName, ".");
28 | Path expression = root.get(names[0]);
29 | for (int i = 1; i < names.length; i++)
30 | {
31 | expression = expression.get(names[i]);
32 | }
33 |
34 | // logic operator
35 | switch (filter.operator)
36 | {
37 | case EQ:
38 | predicates.add(builder.equal(expression, filter.value));
39 | break;
40 | case NE:
41 | predicates.add(builder.notEqual(expression, filter.value));
42 | break;
43 | case LIKE:
44 | predicates.add(builder.like(expression, "%" + filter.value + "%"));
45 | break;
46 | case NOTLIKE:
47 | predicates.add(builder.notLike(expression, "%" + filter.value + "%"));
48 | break;
49 | case GT:
50 | predicates.add(builder.greaterThan(expression, (Comparable)filter.value));
51 | break;
52 | case LT:
53 | predicates.add(builder.lessThan(expression, (Comparable)filter.value));
54 | break;
55 | case GTE:
56 | predicates.add(builder.greaterThanOrEqualTo(expression, (Comparable)filter.value));
57 | break;
58 | case LTE:
59 | predicates.add(builder.lessThanOrEqualTo(expression, (Comparable)filter.value));
60 | break;
61 | case IN:
62 | String[] values = filter.value.toString().split(",");
63 | predicates.add(expression.in(values));
64 | break;
65 | case INLIST:
66 | List ids = (List) filter.value;
67 | predicates.add(expression.in(ids));
68 | break;
69 | case NOTIN:
70 | predicates.add(builder.not(expression.in(filter.value)));
71 | break;
72 | case ISNULL:
73 | predicates.add(builder.isNull(expression));
74 | break;
75 | case ISNOTNULL:
76 | predicates.add(builder.isNotNull(expression));
77 | break;
78 | }
79 | }
80 |
81 | // 将所有条件用 and 联合起来
82 | if (!predicates.isEmpty())
83 | {
84 | return builder.and(predicates.toArray(new Predicate[predicates.size()]));
85 | }
86 | }
87 |
88 | return builder.conjunction();
89 | }
90 | };
91 | }
92 | }
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/jpa/PageUtil.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.util.jpa;
2 | import org.apache.commons.collections.CollectionUtils;
3 | import org.apache.commons.lang3.ArrayUtils;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.apache.commons.lang3.Validate;
6 | import org.springframework.data.domain.PageRequest;
7 | import org.springframework.data.domain.Sort;
8 | import org.springframework.data.domain.Sort.Direction;
9 | import org.springframework.data.jpa.domain.Specification;
10 |
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | /**
15 | *
16 | * 分页工具类
17 | *
18 | */
19 | public class PageUtil
20 | {
21 |
22 | /**
23 | * 创建分页请求.
24 | */
25 | public static PageRequest buildPageRequest(int pageNumber, int pageSize)
26 | {
27 | Sort sort = null;
28 | return buildPageRequest(pageNumber, pageSize, sort);
29 | }
30 |
31 | /**
32 | *
33 | * <创建分页请求,并按照指定的顺序和属性进行排序 单个字段排序>
34 | * <比如direction为"desc",oderBy为id,会按照id降序>
35 | *
36 | * @param pageNumber
37 | * @param pageSize
38 | * @param direction
39 | * @param orderBy
40 | * @return
41 | * @see [类、类#方法、类#成员]
42 | */
43 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, Direction direction, String orderBy)
44 | {
45 | Sort sort = null;
46 | if (null != direction && StringUtils.isNotBlank(orderBy))
47 | {
48 | sort = new Sort(direction, orderBy);
49 | }
50 | return buildPageRequest(pageNumber, pageSize, sort);
51 | }
52 |
53 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, String direction, String... orderBys)
54 | {
55 | Sort sort = null;
56 | if ("desc".equalsIgnoreCase(direction))
57 | {
58 | sort = new Sort(Direction.DESC, orderBys);
59 | }
60 | else
61 | {
62 | sort = new Sort(Direction.ASC, orderBys);
63 | }
64 | return new PageRequest(pageNumber - 1, pageSize, sort);
65 | }
66 |
67 | /**
68 | *
69 | * <创建分页请求,并按照指定的顺序和属性进行排序 排序方向相同的多个字段排序>
70 | * <比如direction为"desc",oderBy为{"id","age"},会按照id降序,然后age降序>
71 | *
72 | * @param pageNumber
73 | * @param pageSize
74 | * @param direction
75 | * @param orderBys
76 | * @return
77 | * @see [类、类#方法、类#成员]
78 | */
79 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, Direction direction, String... orderBys)
80 | {
81 | Sort sort = null;
82 | if (null != direction && ArrayUtils.isNotEmpty(orderBys))
83 | {
84 | sort = new Sort(direction, orderBys);
85 | }
86 | return buildPageRequest(pageNumber, pageSize, sort);
87 | }
88 |
89 | /**
90 | *
91 | * <创建分页请求,并按照指定的顺序和属性进行排序 排序方向相同的多个字段排序>
92 | * <比如direction为"desc",oderBy为{"id","age"},会按照id降序,然后age降序>
93 | *
94 | * @param pageNumber
95 | * @param pageSize
96 | * @param direction
97 | * @param orderBys
98 | * @return
99 | * @see [类、类#方法、类#成员]
100 | */
101 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, Direction direction, List orderBys)
102 | {
103 | Sort sort = null;
104 | if (null != direction && CollectionUtils.isNotEmpty(orderBys))
105 | {
106 | sort = new Sort(direction, orderBys);
107 | }
108 | return buildPageRequest(pageNumber, pageSize, sort);
109 | }
110 |
111 | /**
112 | *
113 | * <创建分页请求,并按照指定的顺序和属性进行排序 排序方向不同的多个字段排序>
114 | * <例如directions中包含排序方向{"asc","desc","asc"},orderBys中包含需要排序的字段
115 | * {"id","age","name"},则排序的效果为先按照id升序,再按age降序,再按name升序排列.directions和oderBys list大小要相同>
116 | *
117 | * @param pageNumber
118 | * @param pageSize
119 | * @param directions
120 | * @param orderBys
121 | * @return
122 | * @see [类、类#方法、类#成员]
123 | */
124 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, List directions,
125 | List orderBys)
126 | {
127 | Sort sort = null;
128 | if (CollectionUtils.isNotEmpty(directions) && CollectionUtils.isNotEmpty(orderBys))
129 | {
130 | Validate.isTrue((directions.size() == orderBys.size()), "directions of size eq to the size of orderBys.");
131 | for (int i = 0, len = directions.size(); i < len; i++)
132 | {
133 | if (i == 0)
134 | {
135 | sort = new Sort(directions.get(i), orderBys.get(i));
136 | }
137 | else
138 | {
139 | sort.and(new Sort(directions.get(i), orderBys.get(i)));
140 | }
141 | }
142 | }
143 | return buildPageRequest(pageNumber, pageSize, sort);
144 | }
145 |
146 | public static PageRequest buildPageRequest(int pageNumber, int pageSize, Sort sort)
147 | {
148 | Validate.isTrue((pageNumber >= 1), "pageNumber must be gte one.");
149 | Validate.isTrue((pageSize >= 1), "pageSize must be gte one.");
150 |
151 | return new PageRequest(pageNumber - 1, pageSize, sort);
152 | }
153 |
154 | /**
155 | *
156 | * <创建动态查询条件组合>
157 | * <功能详细描述>
158 | *
159 | * @param searchParams
160 | * @param t
161 | * @return
162 | * @see [类、类#方法、类#成员]
163 | */
164 | @SuppressWarnings("unchecked")
165 | public static Specification buildSpecification(Map searchParams, Class t)
166 | {
167 | Map filters = SearchFilter.parse(searchParams);
168 | Specification spec = (Specification)DynamicSpecifications.bySearchFilter(filters.values(), t.getClass());
169 | return spec;
170 | }
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/jpa/SearchFilter.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.util.jpa;
2 | import com.google.common.collect.Maps;
3 | import org.apache.commons.lang3.StringUtils;
4 |
5 | import java.util.Map;
6 | import java.util.Map.Entry;
7 |
8 | public class SearchFilter
9 | {
10 | public enum Operator
11 | {
12 | EQ, NE, LIKE, GT, LT, GTE, LTE, IN, INLIST, NOTIN, ISNULL, ISNOTNULL, NOTLIKE
13 | }
14 |
15 | // add by chenbo;
16 | public enum ConjunctionType
17 | {
18 | ADD, OR
19 | }
20 |
21 | public String fieldName;
22 |
23 | public Object value;
24 |
25 | public Operator operator;
26 |
27 | public ConjunctionType conjunctionType;
28 |
29 | public SearchFilter(String fieldName, Operator operator, Object value)
30 | {
31 | this.fieldName = fieldName;
32 | this.value = value;
33 | this.operator = operator;
34 | this.conjunctionType = ConjunctionType.ADD;
35 | }
36 |
37 | public SearchFilter(String fieldName, Operator operator, Object value, ConjunctionType conjunctionType)
38 | {
39 | this.fieldName = fieldName;
40 | this.value = value;
41 | this.operator = operator;
42 | this.conjunctionType = conjunctionType;
43 | }
44 |
45 | /**
46 | * searchParams中key的格式为OPERATOR_FIELDNAME
47 | */
48 | public static Map parse(Map searchParams)
49 | {
50 | Map filters = Maps.newHashMap();
51 |
52 | for (Entry entry : searchParams.entrySet())
53 | {
54 | // 过滤掉空值
55 | String key = entry.getKey();
56 | Object value = entry.getValue();
57 | if (value == null || "".equals(value))
58 | {
59 | continue;
60 | }
61 |
62 | // 拆分operator与filedAttribute
63 | String[] names = StringUtils.split(key, "_");
64 | if (names.length != 2 && names.length != 3)
65 | {
66 | throw new IllegalArgumentException(key + " is not a valid search filter name");
67 | }
68 | String filedName = names[1];
69 | Operator operator = Operator.valueOf(names[0]);
70 | SearchFilter filter;
71 | if (names.length == 3)
72 | {
73 | // 创建searchFilter
74 | filter = new SearchFilter(filedName, operator, value, ConjunctionType.valueOf(names[2]));
75 | }
76 | else
77 | {
78 | // 创建searchFilter
79 | filter = new SearchFilter(filedName, operator, value);
80 | }
81 |
82 | filters.put(key, filter);
83 | }
84 |
85 | return filters;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/live-common/src/main/java/com/easy/live/streaming/common/util/jpa/SerializeUtils.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.common.util.jpa;
2 | import java.io.*;
3 |
4 | public final class SerializeUtils {
5 |
6 |
7 | /**
8 | * deserialize
9 | * @param bytes
10 | * @return
11 | */
12 | public static Object deserialize(byte[] bytes) {
13 |
14 | Object result = null;
15 |
16 | if (isEmpty(bytes)) {
17 | return null;
18 | }
19 |
20 | try {
21 | ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
22 | try {
23 | ObjectInputStream objectInputStream = new ObjectInputStream(byteStream);
24 | try {
25 | result = objectInputStream.readObject();
26 | } catch (ClassNotFoundException ex) {
27 | throw new Exception("Failed to deserialize object type", ex);
28 | }
29 | } catch (Throwable ex) {
30 | throw new Exception("Failed to deserialize", ex);
31 | }
32 | } catch (Exception e) {
33 | // logger.error("Failed to deserialize", e);
34 | }
35 | return result;
36 | }
37 |
38 | public static boolean isEmpty(byte[] data) {
39 | return (data == null || data.length == 0);
40 | }
41 |
42 | /**
43 | * serialize
44 | * @param object
45 | * @return
46 | */
47 | public static byte[] serialize(Object object) {
48 | byte[] result = null;
49 | if (object == null) {
50 | return new byte[0];
51 | }
52 | try {
53 | ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128);
54 | try {
55 | if (!(object instanceof Serializable)) {
56 | throw new IllegalArgumentException(
57 | SerializeUtils.class.getSimpleName() + " requires a Serializable payload "
58 | + "but received an object of type [" + object.getClass().getName() + "]");
59 | }
60 | ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteStream);
61 | objectOutputStream.writeObject(object);
62 | objectOutputStream.flush();
63 | result = byteStream.toByteArray();
64 | } catch (Throwable ex) {
65 | throw new Exception("Failed to serialize", ex);
66 | }
67 | } catch (Exception ex) {
68 | // logger.error("Failed to serialize", ex);
69 | }
70 | return result;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/live-config/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | live-parent
7 | com.easy
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | live-config
13 |
14 |
15 |
16 |
17 | org.springframework.cloud
18 | spring-cloud-starter-eureka
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-tomcat
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-actuator
27 |
28 |
29 |
30 |
31 | org.springframework.cloud
32 | spring-cloud-config-server
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-actuator
37 |
38 |
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-actuator
43 | 1.5.10.RELEASE
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-maven-plugin
53 | 1.5.2.RELEASE
54 |
55 |
56 |
57 | repackage
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/live-config/src/main/java/com/easy/live/streaming/gateway/ConfigApplication.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.gateway;
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication;
4 | import org.springframework.boot.builder.SpringApplicationBuilder;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 | import org.springframework.cloud.config.server.EnableConfigServer;
7 |
8 | /**
9 | * @Description:配置中心服务
10 | * @Author: zhangliangfu
11 | * @Create on: 2019-06-12 19:02
12 | */
13 |
14 | @SpringBootApplication
15 | @EnableDiscoveryClient
16 | @EnableConfigServer
17 | public class ConfigApplication {
18 | public static void main(String[] args) {
19 | new SpringApplicationBuilder(ConfigApplication.class).web(true).run(args);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/live-config/src/main/java/com/easy/live/streaming/gateway/intergration/ApplicationDestroy.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.gateway.intergration;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.DisposableBean;
6 |
7 | public class ApplicationDestroy implements DisposableBean {
8 |
9 | Logger logger = LoggerFactory.getLogger(ApplicationDestroy.class);
10 |
11 | @Override
12 | public void destroy() throws Exception {
13 | logger.info("System [Config] destroy");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/live-config/src/main/java/com/easy/live/streaming/gateway/intergration/AutoConfigure.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.gateway.intergration;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
6 |
7 | @Configuration
8 | public class AutoConfigure extends WebMvcConfigurerAdapter {
9 |
10 | @Bean
11 | StartupRunner startupRunner() {
12 | return new StartupRunner();
13 | }
14 |
15 | @Bean
16 | ApplicationDestroy applicationDestroy() {
17 | return new ApplicationDestroy();
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/live-config/src/main/java/com/easy/live/streaming/gateway/intergration/StartupRunner.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.gateway.intergration;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.boot.CommandLineRunner;
6 |
7 | public class StartupRunner implements CommandLineRunner {
8 |
9 | Logger logger = LoggerFactory.getLogger(StartupRunner.class);
10 |
11 | @Override
12 | public void run(String... args) throws Exception {
13 | logger.info("配置中心服务启动成功");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/live-config/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ____ ___ ___
2 | /\ _`\ /\_ \ __ /'___\
3 | \ \ \L\_\ __ ____ __ __ \//\ \ /\_\/\ \__/ __
4 | \ \ _\L /'__`\ /',__\/\ \/\ \ \ \ \ \/\ \ \ ,__\/'__`\
5 | \ \ \L\ \/\ \L\.\_/\__, `\ \ \_\ \ \_\ \_\ \ \ \ \_/\ __/
6 | \ \____/\ \__/.\_\/\____/\/`____ \ /\____\\ \_\ \_\\ \____\
7 | \/___/ \/__/\/_/\/___/ `/___/> \ \/____/ \/_/\/_/ \/____/
8 | /\___/
9 | \/__/
--------------------------------------------------------------------------------
/live-config/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | easy:
2 | eurekaServer: http://live.registry.com:8001/eureka/
3 |
4 |
5 | server:
6 | port: 8002
7 |
8 | spring:
9 | application:
10 | name: config-server
11 | profiles:
12 | active: native
13 | cloud:
14 | config:
15 | server:
16 | native:
17 | search-locations: classpath:/config/
18 | default-label: dev
19 |
20 | management:
21 | security:
22 | enabled: false
23 |
24 | eureka:
25 | instance:
26 | preferIpAddress: true
27 | client:
28 | serviceUrl:
29 | defaultZone: ${easy.eurekaServer}
30 |
31 |
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/dev/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | http:
3 | multipart:
4 | max-file-size: 50Mb
5 | max-request-size: 100Mb
6 | enabled: true
7 | cloud:
8 | loadbalancer:
9 | retry:
10 | enabled: true
11 | datasource:
12 | driver-class-name: com.mysql.jdbc.Driver
13 | name: habits
14 | url: jdbc:mysql://x.x.x.x:3306/video_live?useUnicode=true&characterEncoding=UTF-8
15 | username: xxx
16 | password: xxxx
17 | jpa:
18 | show-sql: false
19 | generate-ddl: true
20 | hibernate.ddl-auto: update
21 | database-platform: org.hibernate.dialect.MySQL5Dialect
22 | redis:
23 | host: xxxxxx
24 | password: xxxx
25 | database: 0
26 | timeout: 3000
27 | port: 1218
28 | session:
29 | store-type: redis
30 |
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/dev/gateway-server-dev.yml:
--------------------------------------------------------------------------------
1 |
2 | zuul:
3 | #add-host-header: true #网关在进行请求路由转发前为请求设置Host头信息
4 | sensitiveHeaders: Session,Origin,Cookie,Set-Cookie,Authorization
5 | semaphore:
6 | max-semaphores: 5000
7 | routes:
8 | video-route:
9 | path: /video-server/**
10 | serviceId: video-server
11 | user-route:
12 | path: /user-server/**
13 | serviceId: user-server
14 | auth-route:
15 | path: /auth-server/**
16 | serviceId: auth-server
17 | error:
18 | path: /gw/error
19 |
20 | server:
21 | connection-timeout: 3000
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/dev/user-server-dev.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangfuz/live-streaming/0ae1727ad2eda591d9eea4f57e03fff6d2b87375/live-config/src/main/resources/config/dev/user-server-dev.yml
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/dev/video-server-dev.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangfuz/live-streaming/0ae1727ad2eda591d9eea4f57e03fff6d2b87375/live-config/src/main/resources/config/dev/video-server-dev.yml
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/prod/application-prod.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangfuz/live-streaming/0ae1727ad2eda591d9eea4f57e03fff6d2b87375/live-config/src/main/resources/config/prod/application-prod.yml
--------------------------------------------------------------------------------
/live-config/src/main/resources/config/test/application-test.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liangfuz/live-streaming/0ae1727ad2eda591d9eea4f57e03fff6d2b87375/live-config/src/main/resources/config/test/application-test.yml
--------------------------------------------------------------------------------
/live-data/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | live-parent
7 | com.easy
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | com.easy
13 | live-data
14 |
15 |
16 |
17 | org.projectlombok
18 | lombok
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-data-jpa
23 |
24 |
25 | com.fasterxml.jackson.core
26 | jackson-annotations
27 |
28 |
29 | org.apache.commons
30 | commons-lang3
31 |
32 |
33 | org.springframework.data
34 | spring-data-redis
35 |
36 |
37 | org.springframework.data
38 | spring-data-jpa
39 |
40 |
41 | commons-collections
42 | commons-collections
43 |
44 |
45 | com.google.guava
46 | guava
47 |
48 |
49 | com.alibaba
50 | fastjson
51 |
52 |
53 | com.easy
54 | live-common
55 |
56 |
57 | io.springfox
58 | springfox-swagger-ui
59 |
60 |
61 | io.springfox
62 | springfox-swagger2
63 |
64 |
65 |
--------------------------------------------------------------------------------
/live-data/src/main/java/com/easy/live/streaming/data/bean/BaseOutput.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.data.bean;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * @Description: base input
9 | * @Author: zhangliangfu
10 | * @Create on: 2019-06-25 10:59
11 | */
12 |
13 | @Data
14 | public class BaseOutput implements Serializable {
15 | private Integer code;
16 | private String message;
17 | private T data;
18 |
19 | public BaseOutput(Integer code, String message){
20 | this.code = code;
21 | this.message = message;
22 | }
23 |
24 | public BaseOutput(Integer code, String message, T data){
25 | this.code = code;
26 | this.message = message;
27 | this.data = data;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/live-data/src/main/java/com/easy/live/streaming/data/cache/SimpleCacheService.java:
--------------------------------------------------------------------------------
1 | package com.easy.live.streaming.data.cache;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.dao.DataAccessException;
6 | import org.springframework.data.redis.connection.RedisConnection;
7 | import org.springframework.data.redis.core.RedisCallback;
8 | import org.springframework.data.redis.core.StringRedisTemplate;
9 | import org.springframework.stereotype.Component;
10 | import org.springframework.util.StringUtils;
11 |
12 | import java.util.*;
13 | import java.util.concurrent.TimeUnit;
14 |
15 | @Component("simpleCacheService")
16 | public class SimpleCacheService {
17 |
18 | @Autowired
19 | private StringRedisTemplate redisTemplate;
20 |
21 | public Set keys(String pattern) {
22 | return redisTemplate.keys(pattern);
23 | }
24 |
25 | public boolean expire(String key, long timeout) {
26 | return redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
27 | }
28 |
29 | public Boolean exists(String key) {
30 | return redisTemplate.execute(new RedisCallback() {
31 | @Override
32 | public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
33 | return redisConnection.exists(key.getBytes());
34 | }
35 | });
36 | }
37 |
38 | public long increment(String key, long delta) {
39 | return redisTemplate.opsForValue().increment(key, delta);
40 | }
41 |
42 | public void set(String key, T val) {
43 | if (!StringUtils.isEmpty(val)) {
44 | redisTemplate.opsForValue().set(key, JSON.toJSONString(val));
45 | }
46 | }
47 |
48 | public void add(String key, T val, long expire) {
49 | if (!StringUtils.isEmpty(val)) {
50 | redisTemplate.opsForValue().set(key, JSON.toJSONString(val), expire, TimeUnit.SECONDS);
51 | }
52 | }
53 |
54 | public void del(String key) {
55 | redisTemplate.delete(key);
56 | }
57 |
58 | public T get(String key, Class clazz) {
59 | String json = redisTemplate.opsForValue().get(key);
60 | if (!StringUtils.isEmpty(json)) {
61 | return JSON.parseObject(json, clazz);
62 | }
63 | return null;
64 | }
65 |
66 | public void hAdd(String key, String hashKey, T val) {
67 | if (!StringUtils.isEmpty(val)) {
68 | redisTemplate.opsForHash().put(key, hashKey, JSON.toJSONString(val));
69 | }
70 | }
71 |
72 | public T hGet(String key, String hashKey, Class clazz) {
73 | Object obj = redisTemplate.opsForHash().get(key, hashKey);
74 | if (obj != null) {
75 | return JSON.parseObject(obj.toString(), clazz);
76 | }
77 | return null;
78 | }
79 |
80 | public boolean hasKey(String key, String hashKey){
81 | return redisTemplate.opsForHash().hasKey(key, hashKey);
82 | }
83 |
84 | public List hGetArray(String key, String hashKey, Class clazz) {
85 | Object obj = redisTemplate.opsForHash().get(key, hashKey);
86 | if (obj != null) {
87 | return JSON.parseArray(obj.toString(), clazz);
88 | }
89 | return null;
90 | }
91 |
92 | public Map hGetAll(String key, Class clazz) {
93 | Map