361 changed files with 2473 additions and 3895 deletions
@ -0,0 +1,53 @@ |
|||
package org.dromara.common.oss.factory; |
|||
|
|||
import com.aliyuncs.DefaultAcsClient; |
|||
import com.aliyuncs.auth.sts.AssumeRoleRequest; |
|||
import com.aliyuncs.auth.sts.AssumeRoleResponse; |
|||
import com.aliyuncs.exceptions.ClientException; |
|||
import com.aliyuncs.http.MethodType; |
|||
import com.aliyuncs.profile.DefaultProfile; |
|||
import com.aliyuncs.profile.IClientProfile; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.dromara.common.oss.core.OssClient; |
|||
import org.dromara.common.sdk.cloudapi.storage.CredentialsToken; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
|
|||
/** |
|||
* @auther wuyuan |
|||
* @data 2025/2/15 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class AliyunOss { |
|||
|
|||
public static CredentialsToken getCredentials( OssClient client) { |
|||
try { |
|||
String regionId = ""; |
|||
// 添加endpoint。适用于Java SDK 3.12.0及以上版本。
|
|||
DefaultProfile.addEndpoint(regionId, "Sts", "sts.cn-hangzhou.aliyuncs.com"); |
|||
// 添加endpoint。适用于Java SDK 3.12.0以下版本。
|
|||
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
|
|||
// 构造default profile。
|
|||
IClientProfile profile = DefaultProfile.getProfile(regionId, client.getOssProperties().getAccessKey(), client.getOssProperties().getSecretKey()); |
|||
// 构造client。
|
|||
DefaultAcsClient ascClient = new DefaultAcsClient(profile); |
|||
AssumeRoleRequest request = new AssumeRoleRequest(); |
|||
// 适用于Java SDK 3.12.0及以上版本。
|
|||
request.setSysMethod(MethodType.POST); |
|||
// 适用于Java SDK 3.12.0以下版本。
|
|||
//request.setMethod(MethodType.POST);
|
|||
request.setRoleArn(client.getOssProperties().getRoleArn()); |
|||
request.setRoleSessionName(client.getOssProperties().getRoleSessionName()); |
|||
request.setDurationSeconds(client.getOssProperties().getExpire()); |
|||
AssumeRoleResponse response = ascClient.getAcsResponse(request); |
|||
|
|||
return new CredentialsToken(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken(), client.getOssProperties().getExpire()); |
|||
} catch (ClientException e) { |
|||
log.debug("Failed to obtain sts."); |
|||
e.printStackTrace(); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,24 @@ |
|||
package org.dromara.common.oss.factory; |
|||
|
|||
|
|||
import org.dromara.common.oss.core.OssClient; |
|||
import org.dromara.common.sdk.cloudapi.storage.CredentialsToken; |
|||
import org.dromara.common.sdk.cloudapi.storage.OssTypeEnum; |
|||
|
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.3 |
|||
* @date 2021/12/23 |
|||
*/ |
|||
public interface IOssService { |
|||
|
|||
/** |
|||
* Get temporary credentials. |
|||
* @return |
|||
*/ |
|||
CredentialsToken getCredentials(OssClient client); |
|||
|
|||
} |
@ -0,0 +1,37 @@ |
|||
package org.dromara.common.oss.factory; |
|||
|
|||
import com.amazonaws.auth.AWSCredentialsProvider; |
|||
import com.amazonaws.auth.AWSStaticCredentialsProvider; |
|||
import com.amazonaws.auth.BasicAWSCredentials; |
|||
import com.amazonaws.client.builder.AwsClientBuilder; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenService; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; |
|||
import com.amazonaws.services.securitytoken.model.Credentials; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.dromara.common.oss.core.OssClient; |
|||
import org.dromara.common.sdk.cloudapi.storage.CredentialsToken; |
|||
|
|||
/** |
|||
* @auther wuyuan |
|||
* @data 2025/2/15 |
|||
*/ |
|||
@Slf4j |
|||
public class Minio { |
|||
|
|||
public static CredentialsToken getCredentials(OssClient client) { |
|||
try { |
|||
AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(client.getOssProperties().getEndpoint(), client.getOssProperties().getRegion()); |
|||
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(client.getOssProperties().getAccessKey(), client.getOssProperties().getSecretKey()); |
|||
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials); |
|||
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() |
|||
.withEndpointConfiguration(endpointConfiguration) |
|||
.withCredentials(credentialsProvider).build(); |
|||
Credentials credentials = stsClient.getSessionToken().getCredentials(); |
|||
return new CredentialsToken(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), credentials.getSessionToken(), client.getOssProperties().getExpire()); |
|||
} catch (Exception e) { |
|||
log.debug("Failed to obtain sts."); |
|||
e.printStackTrace(); |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -1,4 +1,4 @@ |
|||
package com.dji.sample.component.redis; |
|||
package org.dromara.common.redis.config; |
|||
|
|||
/** |
|||
* @author sean |
@ -1,4 +1,4 @@ |
|||
package com.dji.sample.component.redis; |
|||
package org.dromara.common.redis.utils; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
@ -1,4 +1,4 @@ |
|||
package com.dji.sample.component.websocket.config; |
|||
package org.dromara.common.websocket.config; |
|||
|
|||
import org.springframework.web.socket.WebSocketSession; |
|||
import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator; |
@ -0,0 +1,83 @@ |
|||
package org.dromara.common.websocket.dto; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import jakarta.validation.constraints.Min; |
|||
import jakarta.validation.constraints.NotNull; |
|||
|
|||
|
|||
/** |
|||
* The format of WebSocket messages that the pilot can receive. |
|||
* @author sean.zhou |
|||
* @date 2021/11/17 |
|||
* @version 0.1 |
|||
*/ |
|||
@Schema(description = "The format of WebSocket messages that the pilot can receive.") |
|||
public class WebSocketMessageResponse<T> { |
|||
|
|||
@JsonProperty("biz_code") |
|||
@NotNull |
|||
@Schema(description = "webSocket messages identity", implementation = BizCodeEnum.class) |
|||
private String bizCode; |
|||
|
|||
@Schema(description = "webSocket messages version") |
|||
private String version = "1.0"; |
|||
|
|||
@NotNull |
|||
@Min(123456789012L) |
|||
@Schema(description = "timestamp (milliseconds)") |
|||
private Long timestamp; |
|||
|
|||
@NotNull |
|||
@Schema(description = "Data corresponding to business functions") |
|||
private T data; |
|||
|
|||
public WebSocketMessageResponse() { |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return "WebSocketMessageResponse{" + |
|||
"bizCode=" + bizCode + |
|||
", version='" + version + '\'' + |
|||
", timestamp=" + timestamp + |
|||
", data=" + data + |
|||
'}'; |
|||
} |
|||
|
|||
public String getBizCode() { |
|||
return bizCode; |
|||
} |
|||
|
|||
public WebSocketMessageResponse<T> setBizCode(String bizCode) { |
|||
this.bizCode = bizCode; |
|||
return this; |
|||
} |
|||
|
|||
public String getVersion() { |
|||
return version; |
|||
} |
|||
|
|||
public WebSocketMessageResponse<T> setVersion(String version) { |
|||
this.version = version; |
|||
return this; |
|||
} |
|||
|
|||
public Long getTimestamp() { |
|||
return timestamp; |
|||
} |
|||
|
|||
public WebSocketMessageResponse<T> setTimestamp(Long timestamp) { |
|||
this.timestamp = timestamp; |
|||
return this; |
|||
} |
|||
|
|||
public T getData() { |
|||
return data; |
|||
} |
|||
|
|||
public WebSocketMessageResponse<T> setData(T data) { |
|||
this.data = data; |
|||
return this; |
|||
} |
|||
} |
@ -0,0 +1,138 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
|||
<parent> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>dk-modules</artifactId> |
|||
<version>${revision}</version> |
|||
</parent> |
|||
<modelVersion>4.0.0</modelVersion> |
|||
|
|||
<artifactId>sample</artifactId> |
|||
|
|||
|
|||
|
|||
<dependencies> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-nacos</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-core</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-cloudsdk</artifactId> |
|||
<version>2.2.2</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-sentinel</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- RuoYi Common Log --> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-log</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-dict</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-doc</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-web</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-mybatis</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-dubbo</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-seata</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-idempotent</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-tenant</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-security</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-translation</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-sensitive</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-encrypt</artifactId> |
|||
</dependency> |
|||
|
|||
<!-- RuoYi Api System --> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>api-system</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>api-resource</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-websocket</artifactId> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dom4j</groupId> |
|||
<artifactId>dom4j</artifactId> |
|||
<version>2.1.3</version> |
|||
<scope>compile</scope> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>org.dromara</groupId> |
|||
<artifactId>common-oss</artifactId> |
|||
</dependency> |
|||
|
|||
<dependency> |
|||
<groupId>com.amazonaws</groupId> |
|||
<artifactId>aws-java-sdk-s3</artifactId> |
|||
<version>1.12.261</version> |
|||
</dependency> |
|||
<dependency> |
|||
<groupId>com.amazonaws</groupId> |
|||
<artifactId>aws-java-sdk-sts</artifactId> |
|||
<version>1.12.261</version> |
|||
</dependency> |
|||
</dependencies> |
|||
|
|||
</project> |
@ -1,88 +0,0 @@ |
|||
package com.dji.sample.common.model; |
|||
|
|||
import com.auth0.jwt.interfaces.Claim; |
|||
import com.fasterxml.jackson.annotation.JsonAlias; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.util.Map; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
|
|||
/** |
|||
* A custom claim for storing custom information in the token. |
|||
* @author sean.zhou |
|||
* @date 2021/11/16 |
|||
* @version 0.1 |
|||
*/ |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
@Data |
|||
@Slf4j |
|||
public class CustomClaim { |
|||
|
|||
/** |
|||
* The id of the account. |
|||
*/ |
|||
private String id; |
|||
|
|||
private String username; |
|||
|
|||
@JsonAlias("user_type") |
|||
private Integer userType; |
|||
|
|||
@JsonAlias("workspace_id") |
|||
private String workspaceId; |
|||
|
|||
/** |
|||
* Convert the custom claim data type to the Map type. |
|||
* @return map |
|||
*/ |
|||
public ConcurrentHashMap<String, String> convertToMap() { |
|||
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(4); |
|||
try { |
|||
Field[] declaredFields = this.getClass().getDeclaredFields(); |
|||
for (Field field : declaredFields) { |
|||
JsonAlias annotation = field.getAnnotation(JsonAlias.class); |
|||
field.setAccessible(true); |
|||
// The value of key is named underscore.
|
|||
map.put(annotation != null ? annotation.value()[0] : field.getName(), |
|||
field.get(this).toString()); |
|||
} |
|||
} catch (IllegalAccessException e) { |
|||
log.info("CustomClaim converts failed. {}", this.toString()); |
|||
e.printStackTrace(); |
|||
} |
|||
return map; |
|||
} |
|||
|
|||
/** |
|||
* Convert the data in Map into a custom claim object. |
|||
* @param claimMap |
|||
*/ |
|||
public CustomClaim (Map<String, Claim> claimMap) { |
|||
Field[] declaredFields = this.getClass().getDeclaredFields(); |
|||
for (Field field : declaredFields) { |
|||
field.setAccessible(true); |
|||
JsonAlias annotation = field.getAnnotation(JsonAlias.class); |
|||
|
|||
Claim value = claimMap.get(annotation == null ? field.getName() : annotation.value()[0]); |
|||
try { |
|||
Class<?> type = field.getType(); |
|||
if (Integer.class.equals(type)) { |
|||
field.set(this, Integer.valueOf(value.asString())); |
|||
continue; |
|||
} |
|||
if (String.class.equals(type)) { |
|||
field.set(this, value.asString()); |
|||
continue; |
|||
} |
|||
} catch (IllegalAccessException e) { |
|||
log.info("Claim parses failed. {}", claimMap.toString()); |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,144 +0,0 @@ |
|||
package com.dji.sample.common.util; |
|||
|
|||
import com.auth0.jwt.JWT; |
|||
import com.auth0.jwt.JWTCreator; |
|||
import com.auth0.jwt.algorithms.Algorithm; |
|||
import com.auth0.jwt.exceptions.TokenExpiredException; |
|||
import com.auth0.jwt.interfaces.DecodedJWT; |
|||
import com.dji.sample.common.model.CustomClaim; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.util.*; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
public class JwtUtil { |
|||
|
|||
private static String issuer; |
|||
|
|||
private static String subject; |
|||
|
|||
private static long age; |
|||
|
|||
private static String secret; |
|||
|
|||
public static Algorithm algorithm; |
|||
|
|||
@Value("${jwt.issuer: DJI}") |
|||
private void setIssuer(String issuer) { |
|||
JwtUtil.issuer = issuer; |
|||
} |
|||
|
|||
@Value("${jwt.subject: CloudApiSample}") |
|||
private void setSubject(String subject) { |
|||
JwtUtil.subject = subject; |
|||
} |
|||
|
|||
@Value("${jwt.age: 86400}") |
|||
private void setAge(long age) { |
|||
JwtUtil.age = age * 1000; |
|||
} |
|||
|
|||
@Value("${jwt.secret: CloudApiSample}") |
|||
private void setSecret(String secret) { |
|||
JwtUtil.secret = secret; |
|||
setAlgorithm(); |
|||
} |
|||
|
|||
private void setAlgorithm() { |
|||
JwtUtil.algorithm = Algorithm.HMAC256(secret); |
|||
} |
|||
|
|||
private JwtUtil() { |
|||
|
|||
} |
|||
|
|||
/** |
|||
* Create a token based on custom information. |
|||
* @param claims custom information |
|||
* @return token |
|||
*/ |
|||
public static String createToken(Map<String, ?> claims) { |
|||
return JwtUtil.createToken(claims, age, algorithm, subject, issuer); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
* @param claims |
|||
* @param age unit: s |
|||
* @param algorithm |
|||
* @param subject |
|||
* @param issuer |
|||
* @return |
|||
*/ |
|||
public static String createToken(Map<String, ?> claims, Long age, Algorithm algorithm, String subject, String issuer) { |
|||
if (Objects.isNull(algorithm)) { |
|||
throw new IllegalArgumentException(); |
|||
} |
|||
|
|||
Date now = new Date(); |
|||
JWTCreator.Builder builder = JWT.create(); |
|||
// Add custom information to the token's payload segment.
|
|||
claims.forEach((k, v) -> { |
|||
if (Objects.nonNull(v.getClass().getClassLoader())) { |
|||
log.error("claim can't be set to a custom object."); |
|||
return; |
|||
} |
|||
if (v instanceof Map) { |
|||
builder.withClaim(k, (Map) v); |
|||
} else if (v instanceof List) { |
|||
builder.withClaim(k, (List) v); |
|||
} else { |
|||
builder.withClaim(k, String.valueOf(v)); |
|||
} |
|||
}); |
|||
|
|||
if (StringUtils.hasText(subject)) { |
|||
builder.withSubject(subject); |
|||
} |
|||
|
|||
if (StringUtils.hasText(issuer)) { |
|||
builder.withIssuer(issuer); |
|||
} |
|||
|
|||
if (Objects.nonNull(age)) { |
|||
builder.withExpiresAt(new Date(now.getTime() + age)); |
|||
} |
|||
|
|||
String token = builder |
|||
.withIssuedAt(now) |
|||
.withNotBefore(now) |
|||
.sign(algorithm); |
|||
log.debug("token created. " + token); |
|||
return token; |
|||
} |
|||
|
|||
/** |
|||
* Verify that the token is valid. |
|||
* @param token |
|||
* @return |
|||
* @throws TokenExpiredException |
|||
*/ |
|||
public static DecodedJWT verifyToken(String token) { |
|||
return JWT.require(algorithm).build().verify(token); |
|||
} |
|||
|
|||
/** |
|||
* Parses the custom information in the token into a CustomClaim object. |
|||
* @param token |
|||
* @return custom claim |
|||
*/ |
|||
public static Optional<CustomClaim> parseToken(String token) { |
|||
DecodedJWT jwt; |
|||
try { |
|||
jwt = verifyToken(token); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
return Optional.empty(); |
|||
} |
|||
return Optional.of(new CustomClaim(jwt.getClaims())); |
|||
} |
|||
} |
@ -1,60 +0,0 @@ |
|||
package com.dji.sample.component; |
|||
|
|||
import com.dji.sample.common.error.CommonErrorEnum; |
|||
import com.dji.sample.common.model.CustomClaim; |
|||
import com.dji.sample.common.util.JwtUtil; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.http.HttpMethod; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.servlet.HandlerInterceptor; |
|||
import org.springframework.web.servlet.ModelAndView; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.util.Optional; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
public class AuthInterceptor implements HandlerInterceptor { |
|||
|
|||
public static final String PARAM_TOKEN = "x-auth-token"; |
|||
|
|||
public static final String TOKEN_CLAIM = "customClaim"; |
|||
|
|||
@Override |
|||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
|||
String uri = request.getRequestURI(); |
|||
log.debug("request uri: {}, IP: {}", uri, request.getRemoteAddr()); |
|||
// The options method is passed directly.
|
|||
if (HttpMethod.OPTIONS.matches(request.getMethod())) { |
|||
response.setStatus(HttpStatus.OK.value()); |
|||
return false; |
|||
} |
|||
String token = request.getHeader(PARAM_TOKEN); |
|||
// Check if the token exists.
|
|||
if (!StringUtils.hasText(token)) { |
|||
response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|||
log.error(CommonErrorEnum.NO_TOKEN.getMessage()); |
|||
return false; |
|||
} |
|||
|
|||
// Check if the current token is valid.
|
|||
Optional<CustomClaim> customClaimOpt = JwtUtil.parseToken(token); |
|||
if (customClaimOpt.isEmpty()) { |
|||
response.setStatus(HttpStatus.UNAUTHORIZED.value()); |
|||
return false; |
|||
} |
|||
|
|||
// Put the custom data from the token into the request.
|
|||
request.setAttribute(TOKEN_CLAIM, customClaimOpt.get()); |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { |
|||
// Delete the custom data in the request after the request ends.
|
|||
request.removeAttribute(TOKEN_CLAIM); |
|||
} |
|||
} |
@ -1,35 +0,0 @@ |
|||
package com.dji.sample.component; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.servlet.*; |
|||
import javax.servlet.http.HttpServletRequest; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
|
|||
import static com.dji.sample.component.AuthInterceptor.PARAM_TOKEN; |
|||
|
|||
/** |
|||
* @author sean.zhou |
|||
* @version 0.1 |
|||
* @date 2021/11/22 |
|||
*/ |
|||
@Component |
|||
public class CorsFilter implements Filter { |
|||
|
|||
@Override |
|||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { |
|||
HttpServletResponse res = (HttpServletResponse) response; |
|||
res.addHeader("Access-Control-Allow-Credentials", "true"); |
|||
res.addHeader("Access-Control-Allow-Origin", "*"); |
|||
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); |
|||
res.addHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers," + |
|||
"Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, "+ |
|||
"Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive," + |
|||
" User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma," + PARAM_TOKEN); |
|||
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) { |
|||
return; |
|||
} |
|||
filterChain.doFilter(request, response); |
|||
} |
|||
} |
@ -1,24 +0,0 @@ |
|||
package com.dji.sample.component.mybatis; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.DbType; |
|||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
|||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.3 |
|||
* @date 2021/12/22 |
|||
*/ |
|||
@Configuration |
|||
public class MybatisPlusConfiguration { |
|||
|
|||
@Bean |
|||
public MybatisPlusInterceptor mybatisPlusInterceptor() { |
|||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
|||
// select database
|
|||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); |
|||
return interceptor; |
|||
} |
|||
} |
@ -1,37 +0,0 @@ |
|||
package com.dji.sample.component.mybatis; |
|||
|
|||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
|||
import org.apache.ibatis.reflection.MetaObject; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.time.LocalDateTime; |
|||
import java.time.ZoneId; |
|||
|
|||
/** |
|||
* Automatic filling for set values |
|||
*/ |
|||
@Component |
|||
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler { |
|||
|
|||
/** |
|||
* Automatic filling when inserting into the database. |
|||
* @param metaObject |
|||
*/ |
|||
@Override |
|||
public void insertFill(MetaObject metaObject) { |
|||
this.strictInsertFill(metaObject, "createTime", Long.class, |
|||
LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); |
|||
this.strictInsertFill(metaObject, "updateTime", Long.class, |
|||
LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); |
|||
} |
|||
|
|||
/** |
|||
* Automatic filling when updating the data. |
|||
* @param metaObject |
|||
*/ |
|||
@Override |
|||
public void updateFill(MetaObject metaObject) { |
|||
this.strictUpdateFill(metaObject, "updateTime", Long.class, |
|||
LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); |
|||
} |
|||
} |
@ -1,93 +0,0 @@ |
|||
package com.dji.sample.component.oss.model; |
|||
|
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.2 |
|||
* @date 2021/12/9 |
|||
*/ |
|||
@ConfigurationProperties(prefix = "oss") |
|||
@Component |
|||
public class OssConfiguration { |
|||
|
|||
/** |
|||
* @see OssTypeEnum |
|||
*/ |
|||
public static OssTypeEnum provider; |
|||
|
|||
/** |
|||
* Whether to use the object storage service. |
|||
*/ |
|||
public static boolean enable; |
|||
|
|||
/** |
|||
* The protocol needs to be included at the beginning of the address. |
|||
*/ |
|||
public static String endpoint; |
|||
|
|||
public static String accessKey; |
|||
|
|||
public static String secretKey; |
|||
|
|||
public static String region; |
|||
|
|||
public static Long expire; |
|||
|
|||
public static String roleSessionName; |
|||
|
|||
public static String roleArn; |
|||
|
|||
public static String bucket; |
|||
|
|||
public static String objectDirPrefix; |
|||
|
|||
public void setProvider(OssTypeEnum provider) { |
|||
OssConfiguration.provider = provider; |
|||
} |
|||
|
|||
public void setEnable(boolean enable) { |
|||
OssConfiguration.enable = enable; |
|||
} |
|||
|
|||
public void setEndpoint(String endpoint) { |
|||
OssConfiguration.endpoint = endpoint; |
|||
} |
|||
|
|||
public void setAccessKey(String accessKey) { |
|||
OssConfiguration.accessKey = accessKey; |
|||
} |
|||
|
|||
public void setSecretKey(String secretKey) { |
|||
OssConfiguration.secretKey = secretKey; |
|||
} |
|||
|
|||
public void setRegion(String region) { |
|||
OssConfiguration.region = region; |
|||
} |
|||
|
|||
public void setExpire(Long expire) { |
|||
OssConfiguration.expire = expire; |
|||
} |
|||
|
|||
public void setRoleSessionName(String roleSessionName) { |
|||
OssConfiguration.roleSessionName = roleSessionName; |
|||
} |
|||
|
|||
public void setRoleArn(String roleArn) { |
|||
OssConfiguration.roleArn = roleArn; |
|||
} |
|||
|
|||
public void setBucket(String bucket) { |
|||
OssConfiguration.bucket = bucket; |
|||
} |
|||
|
|||
public void setObjectDirPrefix(String objectDirPrefix) { |
|||
OssConfiguration.objectDirPrefix = objectDirPrefix; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
@ -1,51 +0,0 @@ |
|||
package com.dji.sample.component.oss.service; |
|||
|
|||
import com.dji.sdk.cloudapi.storage.CredentialsToken; |
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
|
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.3 |
|||
* @date 2021/12/23 |
|||
*/ |
|||
public interface IOssService { |
|||
|
|||
OssTypeEnum getOssType(); |
|||
|
|||
/** |
|||
* Get temporary credentials. |
|||
* @return |
|||
*/ |
|||
CredentialsToken getCredentials(); |
|||
|
|||
/** |
|||
* Get the address of the object based on the bucket name and the object name. |
|||
* @param bucket bucket name |
|||
* @param objectKey object name |
|||
* @return download link |
|||
*/ |
|||
URL getObjectUrl(String bucket, String objectKey); |
|||
|
|||
/** |
|||
* Deletes the object in the storage bucket. |
|||
* @param bucket |
|||
* @param objectKey |
|||
* @return |
|||
*/ |
|||
Boolean deleteObject(String bucket, String objectKey); |
|||
|
|||
/** |
|||
* Get the contents of an object. |
|||
* @param bucket |
|||
* @param objectKey |
|||
* @return |
|||
*/ |
|||
InputStream getObject(String bucket, String objectKey); |
|||
|
|||
void putObject(String bucket, String objectKey, InputStream input); |
|||
|
|||
void createClient(); |
|||
} |
@ -1,120 +0,0 @@ |
|||
package com.dji.sample.component.oss.service.impl; |
|||
|
|||
import com.aliyun.oss.OSS; |
|||
import com.aliyun.oss.OSSClientBuilder; |
|||
import com.aliyun.oss.OSSException; |
|||
import com.aliyun.oss.model.ObjectMetadata; |
|||
import com.aliyun.oss.model.PutObjectRequest; |
|||
import com.aliyun.oss.model.PutObjectResult; |
|||
import com.aliyuncs.DefaultAcsClient; |
|||
import com.aliyuncs.IAcsClient; |
|||
import com.aliyuncs.exceptions.ClientException; |
|||
import com.aliyuncs.http.MethodType; |
|||
import com.aliyuncs.profile.DefaultProfile; |
|||
import com.aliyuncs.profile.IClientProfile; |
|||
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; |
|||
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; |
|||
import com.dji.sample.component.oss.model.OssConfiguration; |
|||
import com.dji.sample.component.oss.service.IOssService; |
|||
import com.dji.sdk.cloudapi.storage.CredentialsToken; |
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
import java.util.Date; |
|||
import java.util.Objects; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.3 |
|||
* @date 2021/12/23 |
|||
*/ |
|||
@Service |
|||
@Slf4j |
|||
public class AliyunOssServiceImpl implements IOssService { |
|||
|
|||
private OSS ossClient; |
|||
|
|||
@Override |
|||
public OssTypeEnum getOssType() { |
|||
return OssTypeEnum.ALIYUN; |
|||
} |
|||
|
|||
@Override |
|||
public CredentialsToken getCredentials() { |
|||
|
|||
try { |
|||
|
|||
|
|||
String regionId = ""; |
|||
// 添加endpoint。适用于Java SDK 3.12.0及以上版本。
|
|||
DefaultProfile.addEndpoint(regionId, "Sts", "sts.cn-hangzhou.aliyuncs.com"); |
|||
// 添加endpoint。适用于Java SDK 3.12.0以下版本。
|
|||
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
|
|||
// 构造default profile。
|
|||
IClientProfile profile = DefaultProfile.getProfile(regionId, OssConfiguration.accessKey, OssConfiguration.secretKey); |
|||
// 构造client。
|
|||
DefaultAcsClient client = new DefaultAcsClient(profile); |
|||
AssumeRoleRequest request = new AssumeRoleRequest(); |
|||
// 适用于Java SDK 3.12.0及以上版本。
|
|||
request.setSysMethod(MethodType.POST); |
|||
// 适用于Java SDK 3.12.0以下版本。
|
|||
//request.setMethod(MethodType.POST);
|
|||
request.setRoleArn(OssConfiguration.roleArn); |
|||
request.setRoleSessionName(OssConfiguration.roleSessionName); |
|||
request.setDurationSeconds(OssConfiguration.expire); |
|||
AssumeRoleResponse response = client.getAcsResponse(request); |
|||
|
|||
return new CredentialsToken(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken(), OssConfiguration.expire); |
|||
} catch (ClientException e) { |
|||
log.debug("Failed to obtain sts."); |
|||
e.printStackTrace(); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public URL getObjectUrl(String bucket, String objectKey) { |
|||
// First check if the object can be fetched.
|
|||
boolean isExist = ossClient.doesObjectExist(bucket, objectKey); |
|||
if (!isExist) { |
|||
throw new OSSException("The object does not exist."); |
|||
} |
|||
|
|||
return ossClient.generatePresignedUrl(bucket, objectKey, |
|||
new Date(System.currentTimeMillis() + OssConfiguration.expire * 1000)); |
|||
} |
|||
|
|||
@Override |
|||
public Boolean deleteObject(String bucket, String objectKey) { |
|||
if (!ossClient.doesObjectExist(bucket, objectKey)) { |
|||
return true; |
|||
} |
|||
ossClient.deleteObject(bucket, objectKey); |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public InputStream getObject(String bucket, String objectKey) { |
|||
return ossClient.getObject(bucket, objectKey).getObjectContent(); |
|||
} |
|||
|
|||
@Override |
|||
public void putObject(String bucket, String objectKey, InputStream input) { |
|||
if (ossClient.doesObjectExist(bucket, objectKey)) { |
|||
throw new RuntimeException("The filename already exists."); |
|||
} |
|||
PutObjectResult objectResult = ossClient.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); |
|||
log.info("Upload FlighttaskCreateFile: {}", objectResult.getETag()); |
|||
} |
|||
|
|||
public void createClient() { |
|||
if (Objects.nonNull(this.ossClient)) { |
|||
return; |
|||
} |
|||
this.ossClient = new OSSClientBuilder() |
|||
.build(OssConfiguration.endpoint, OssConfiguration.accessKey, OssConfiguration.secretKey); |
|||
} |
|||
} |
@ -1,126 +0,0 @@ |
|||
package com.dji.sample.component.oss.service.impl; |
|||
|
|||
import com.amazonaws.HttpMethod; |
|||
import com.amazonaws.auth.AWSStaticCredentialsProvider; |
|||
import com.amazonaws.auth.BasicAWSCredentials; |
|||
import com.amazonaws.services.s3.AmazonS3; |
|||
import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
|||
import com.amazonaws.services.s3.model.*; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenService; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; |
|||
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest; |
|||
import com.amazonaws.services.securitytoken.model.AssumeRoleResult; |
|||
import com.amazonaws.services.securitytoken.model.Credentials; |
|||
import com.dji.sample.component.AuthInterceptor; |
|||
import com.dji.sample.component.oss.model.OssConfiguration; |
|||
import com.dji.sample.component.oss.service.IOssService; |
|||
import com.dji.sdk.cloudapi.storage.CredentialsToken; |
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import javax.annotation.PostConstruct; |
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
import java.util.ArrayList; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
import java.util.Objects; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.0 |
|||
* @date 2022/4/27 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class AmazonS3ServiceImpl implements IOssService { |
|||
|
|||
private AmazonS3 client; |
|||
|
|||
@Override |
|||
public OssTypeEnum getOssType() { |
|||
return OssTypeEnum.AWS; |
|||
} |
|||
|
|||
@Override |
|||
public CredentialsToken getCredentials() { |
|||
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() |
|||
.withCredentials(new AWSStaticCredentialsProvider( |
|||
new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) |
|||
.withRegion(OssConfiguration.region).build(); |
|||
|
|||
AssumeRoleRequest request = new AssumeRoleRequest() |
|||
.withRoleArn(OssConfiguration.roleArn) |
|||
.withRoleSessionName(OssConfiguration.roleSessionName) |
|||
.withDurationSeconds(Math.toIntExact(OssConfiguration.expire)); |
|||
AssumeRoleResult result = stsClient.assumeRole(request); |
|||
Credentials credentials = result.getCredentials(); |
|||
return new CredentialsToken(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), |
|||
credentials.getSessionToken(), (credentials.getExpiration().getTime() - System.currentTimeMillis()) / 1000); |
|||
} |
|||
|
|||
@Override |
|||
public URL getObjectUrl(String bucket, String objectKey) { |
|||
return client.generatePresignedUrl(bucket, objectKey, |
|||
new Date(System.currentTimeMillis() + OssConfiguration.expire * 1000), HttpMethod.GET); |
|||
} |
|||
|
|||
@Override |
|||
public Boolean deleteObject(String bucket, String objectKey) { |
|||
if (!client.doesObjectExist(bucket, objectKey)) { |
|||
return true; |
|||
} |
|||
client.deleteObject(bucket, objectKey); |
|||
return true; |
|||
} |
|||
|
|||
public InputStream getObject(String bucket, String objectKey) { |
|||
return client.getObject(bucket, objectKey).getObjectContent().getDelegateStream(); |
|||
} |
|||
|
|||
@Override |
|||
public void putObject(String bucket, String objectKey, InputStream input) { |
|||
if (client.doesObjectExist(bucket, objectKey)) { |
|||
throw new RuntimeException("The filename already exists."); |
|||
} |
|||
PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata())); |
|||
log.info("Upload FlighttaskCreateFile: {}", objectResult.toString()); |
|||
} |
|||
|
|||
public void createClient() { |
|||
if (Objects.nonNull(this.client)) { |
|||
return; |
|||
} |
|||
this.client = AmazonS3ClientBuilder.standard() |
|||
.withCredentials( |
|||
new AWSStaticCredentialsProvider( |
|||
new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey))) |
|||
.withRegion(OssConfiguration.region) |
|||
.build(); |
|||
} |
|||
|
|||
/** |
|||
* Configuring cross-origin resource sharing |
|||
*/ |
|||
@PostConstruct |
|||
private void configCORS() { |
|||
if (!OssConfiguration.enable || !OssTypeEnum.AWS.getType().equals(OssConfiguration.provider)) { |
|||
return; |
|||
} |
|||
List<CORSRule.AllowedMethods> allowedMethods = new ArrayList<>(); |
|||
allowedMethods.add(CORSRule.AllowedMethods.GET); |
|||
allowedMethods.add(CORSRule.AllowedMethods.POST); |
|||
allowedMethods.add(CORSRule.AllowedMethods.DELETE); |
|||
|
|||
CORSRule rule = new CORSRule() |
|||
.withId("CORSAccessRule") |
|||
.withAllowedOrigins(List.of("*")) |
|||
.withAllowedHeaders(List.of(AuthInterceptor.PARAM_TOKEN)) |
|||
.withAllowedMethods(allowedMethods); |
|||
|
|||
client.setBucketCrossOriginConfiguration(OssConfiguration.bucket, |
|||
new BucketCrossOriginConfiguration().withRules(rule)); |
|||
|
|||
} |
|||
} |
@ -1,140 +0,0 @@ |
|||
package com.dji.sample.component.oss.service.impl; |
|||
|
|||
import com.amazonaws.auth.AWSCredentialsProvider; |
|||
import com.amazonaws.auth.AWSStaticCredentialsProvider; |
|||
import com.amazonaws.auth.BasicAWSCredentials; |
|||
import com.amazonaws.auth.BasicSessionCredentials; |
|||
import com.amazonaws.client.builder.AwsClientBuilder; |
|||
import com.amazonaws.services.s3.AmazonS3; |
|||
import com.amazonaws.services.s3.AmazonS3ClientBuilder; |
|||
import com.amazonaws.services.s3.model.S3Object; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenService; |
|||
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder; |
|||
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest; |
|||
import com.amazonaws.services.securitytoken.model.AssumeRoleResult; |
|||
import com.amazonaws.services.securitytoken.model.Credentials; |
|||
import com.dji.sample.component.oss.model.OssConfiguration; |
|||
import com.dji.sample.component.oss.service.IOssService; |
|||
import com.dji.sdk.cloudapi.storage.CredentialsToken; |
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
import io.minio.*; |
|||
import io.minio.credentials.AssumeRoleProvider; |
|||
import io.minio.errors.*; |
|||
import io.minio.http.Method; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.io.ByteArrayInputStream; |
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
import java.security.InvalidKeyException; |
|||
import java.security.NoSuchAlgorithmException; |
|||
import java.util.Objects; |
|||
|
|||
import static com.dji.sample.component.oss.model.OssConfiguration.*; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.3 |
|||
* @date 2021/12/23 |
|||
*/ |
|||
@Service |
|||
@Slf4j |
|||
public class MinIOServiceImpl implements IOssService { |
|||
|
|||
private MinioClient client; |
|||
|
|||
@Override |
|||
public OssTypeEnum getOssType() { |
|||
return OssTypeEnum.MINIO; |
|||
} |
|||
|
|||
@Override |
|||
public CredentialsToken getCredentials() { |
|||
try { |
|||
AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, region); |
|||
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey); |
|||
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(basicAWSCredentials); |
|||
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard() |
|||
.withEndpointConfiguration(endpointConfiguration) |
|||
.withCredentials(credentialsProvider).build(); |
|||
Credentials credentials = stsClient.getSessionToken().getCredentials(); |
|||
return new CredentialsToken(credentials.getAccessKeyId(), credentials.getSecretAccessKey(), credentials.getSessionToken(), OssConfiguration.expire); |
|||
} catch (Exception e) { |
|||
log.debug("Failed to obtain sts."); |
|||
e.printStackTrace(); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
@Override |
|||
public URL getObjectUrl(String bucket, String objectKey) { |
|||
try { |
|||
return new URL( |
|||
client.getPresignedObjectUrl( |
|||
GetPresignedObjectUrlArgs.builder() |
|||
.method(Method.GET) |
|||
.bucket(bucket) |
|||
.object(objectKey) |
|||
.expiry(Math.toIntExact(OssConfiguration.expire)) |
|||
.build())); |
|||
} catch (ErrorResponseException | InsufficientDataException | InternalException | |
|||
InvalidKeyException | InvalidResponseException | IOException | |
|||
NoSuchAlgorithmException | XmlParserException | ServerException e) { |
|||
throw new RuntimeException("The file does not exist on the OssConfiguration."); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public Boolean deleteObject(String bucket, String objectKey) { |
|||
try { |
|||
client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
|||
} catch (MinioException | NoSuchAlgorithmException | IOException | InvalidKeyException e) { |
|||
log.error("Failed to delete file."); |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public InputStream getObject(String bucket, String objectKey) { |
|||
try { |
|||
GetObjectResponse object = client.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
|||
return new ByteArrayInputStream(object.readAllBytes()); |
|||
} catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException | XmlParserException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
return InputStream.nullInputStream(); |
|||
} |
|||
|
|||
@Override |
|||
public void putObject(String bucket, String objectKey, InputStream input) { |
|||
try { |
|||
client.statObject(StatObjectArgs.builder().bucket(bucket).object(objectKey).build()); |
|||
throw new RuntimeException("The filename already exists."); |
|||
} catch (MinioException | InvalidKeyException | IOException | NoSuchAlgorithmException e) { |
|||
log.info("The file does not exist, start uploading."); |
|||
try { |
|||
ObjectWriteResponse response = client.putObject( |
|||
PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(input, input.available(), 0).build()); |
|||
log.info("Upload FlighttaskCreateFile: {}", response.etag()); |
|||
} catch (MinioException | IOException | InvalidKeyException | NoSuchAlgorithmException ex) { |
|||
log.error("Failed to upload FlighttaskCreateFile {}.", objectKey); |
|||
ex.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public void createClient() { |
|||
if (Objects.nonNull(this.client)) { |
|||
return; |
|||
} |
|||
this.client = MinioClient.builder() |
|||
.endpoint(OssConfiguration.endpoint) |
|||
.credentials(accessKey, secretKey) |
|||
.region(region) |
|||
.build(); |
|||
} |
|||
} |
@ -1,31 +0,0 @@ |
|||
package com.dji.sample.component.oss.service.impl; |
|||
|
|||
import com.dji.sample.component.oss.model.OssConfiguration; |
|||
import org.aspectj.lang.annotation.Aspect; |
|||
import org.aspectj.lang.annotation.Before; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.1 |
|||
* @date 2022/6/20 |
|||
*/ |
|||
@Component |
|||
@Aspect |
|||
public class OssAspectHandler { |
|||
|
|||
@Autowired |
|||
private OssServiceContext ossServiceContext; |
|||
|
|||
@Before("execution(public * com.dji.sample.component.oss.service.impl.OssServiceContext.*(..))") |
|||
public void before() { |
|||
if (!OssConfiguration.enable) { |
|||
throw new IllegalArgumentException("请启用OSS配置。"); |
|||
} |
|||
if (this.ossServiceContext.getOssService() == null) { |
|||
throw new IllegalArgumentException("请检查OSS配置配置。"); |
|||
} |
|||
this.ossServiceContext.createClient(); |
|||
} |
|||
} |
@ -1,68 +0,0 @@ |
|||
package com.dji.sample.component.oss.service.impl; |
|||
|
|||
import com.dji.sample.component.oss.model.OssConfiguration; |
|||
import com.dji.sample.component.oss.service.IOssService; |
|||
import com.dji.sdk.cloudapi.storage.CredentialsToken; |
|||
import com.dji.sdk.cloudapi.storage.OssTypeEnum; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.io.InputStream; |
|||
import java.net.URL; |
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.0 |
|||
* @date 2022/5/30 |
|||
*/ |
|||
@Service |
|||
public class OssServiceContext { |
|||
|
|||
private IOssService ossService; |
|||
|
|||
@Autowired |
|||
public OssServiceContext(List<IOssService> ossServices, OssConfiguration configuration) { |
|||
if (!OssConfiguration.enable) { |
|||
return; |
|||
} |
|||
this.ossService = ossServices.stream() |
|||
.filter(ossService -> ossService.getOssType() == OssConfiguration.provider) |
|||
.findFirst() |
|||
.orElseThrow(() -> new IllegalArgumentException("Oss提供程序非法。可选: " + |
|||
Arrays.toString(Arrays.stream(OssTypeEnum.values()).map(OssTypeEnum::getType).toArray()))); |
|||
} |
|||
|
|||
IOssService getOssService() { |
|||
return this.ossService; |
|||
} |
|||
|
|||
public CredentialsToken getCredentials() { |
|||
return this.ossService.getCredentials(); |
|||
} |
|||
|
|||
public URL getObjectUrl(String bucket, String objectKey) { |
|||
if (!StringUtils.hasText(bucket) || !StringUtils.hasText(objectKey)) { |
|||
throw new IllegalArgumentException(); |
|||
} |
|||
return this.ossService.getObjectUrl(bucket, objectKey); |
|||
} |
|||
|
|||
public Boolean deleteObject(String bucket, String objectKey) { |
|||
return this.ossService.deleteObject(bucket, objectKey); |
|||
} |
|||
|
|||
public InputStream getObject(String bucket, String objectKey) { |
|||
return this.ossService.getObject(bucket, objectKey); |
|||
} |
|||
|
|||
public void putObject(String bucket, String objectKey, InputStream stream) { |
|||
this.ossService.putObject(bucket, objectKey, stream); |
|||
} |
|||
|
|||
void createClient() { |
|||
this.ossService.createClient(); |
|||
} |
|||
} |
@ -1,63 +0,0 @@ |
|||
package com.dji.sample.component.redis; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonInclude; |
|||
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
|||
import com.fasterxml.jackson.databind.MapperFeature; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
|||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; |
|||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; |
|||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; |
|||
import org.springframework.data.redis.serializer.StringRedisSerializer; |
|||
|
|||
import java.time.LocalDateTime; |
|||
import java.time.format.DateTimeFormatter; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.0 |
|||
* @date 2022/4/19 |
|||
*/ |
|||
@Configuration |
|||
@EnableRedisRepositories |
|||
public class RedisConfiguration { |
|||
|
|||
@Bean |
|||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
|||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); |
|||
redisTemplate.setConnectionFactory(factory); |
|||
|
|||
ObjectMapper objectMapper = new ObjectMapper(); |
|||
JavaTimeModule timeModule = new JavaTimeModule(); |
|||
timeModule.addDeserializer(LocalDateTime.class, |
|||
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
|||
timeModule.addSerializer(LocalDateTime.class, |
|||
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
|||
objectMapper.disable(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS); |
|||
objectMapper.registerModules(timeModule); |
|||
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), |
|||
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); |
|||
|
|||
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); |
|||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); |
|||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
|||
|
|||
|
|||
StringRedisSerializer serializer = new StringRedisSerializer(); |
|||
redisTemplate.setKeySerializer(serializer); |
|||
redisTemplate.setHashKeySerializer(serializer); |
|||
|
|||
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper); |
|||
redisTemplate.setValueSerializer(jsonRedisSerializer); |
|||
redisTemplate.setHashValueSerializer(jsonRedisSerializer); |
|||
redisTemplate.afterPropertiesSet(); |
|||
return redisTemplate; |
|||
|
|||
} |
|||
} |
@ -1,70 +0,0 @@ |
|||
package com.dji.sample.component.websocket.config; |
|||
|
|||
import com.dji.sample.common.model.CustomClaim; |
|||
import com.dji.sample.common.util.JwtUtil; |
|||
import com.dji.sample.component.AuthInterceptor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.http.server.ServerHttpRequest; |
|||
import org.springframework.http.server.ServletServerHttpRequest; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.socket.WebSocketHandler; |
|||
import org.springframework.web.socket.server.support.DefaultHandshakeHandler; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.security.Principal; |
|||
import java.util.Map; |
|||
import java.util.Optional; |
|||
|
|||
/** |
|||
* @author sean.zhou |
|||
* @date 2021/11/16 |
|||
* @version 0.1 |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class AuthPrincipalHandler extends DefaultHandshakeHandler { |
|||
|
|||
@Override |
|||
protected boolean isValidOrigin(ServerHttpRequest request) { |
|||
|
|||
if (request instanceof ServletServerHttpRequest) { |
|||
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); |
|||
String token = servletRequest.getParameter(AuthInterceptor.PARAM_TOKEN); |
|||
|
|||
if (!StringUtils.hasText(token)) { |
|||
return false; |
|||
} |
|||
log.debug("token:" + token); |
|||
Optional<CustomClaim> customClaim = JwtUtil.parseToken(token); |
|||
if (customClaim.isEmpty()) { |
|||
return false; |
|||
} |
|||
|
|||
servletRequest.setAttribute(AuthInterceptor.TOKEN_CLAIM, customClaim.get()); |
|||
return true; |
|||
} |
|||
return false; |
|||
|
|||
} |
|||
|
|||
/** |
|||
* The principal's name: {workspaceId}/{userType}/{userId} |
|||
* @param request |
|||
* @param wsHandler |
|||
* @param attributes |
|||
* @return |
|||
*/ |
|||
@Override |
|||
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) { |
|||
if (request instanceof ServletServerHttpRequest) { |
|||
|
|||
// get the custom claim
|
|||
CustomClaim claim = (CustomClaim) ((ServletServerHttpRequest) request).getServletRequest() |
|||
.getAttribute(AuthInterceptor.TOKEN_CLAIM); |
|||
|
|||
return () -> claim.getWorkspaceId() + "/" + claim.getUserType() + "/" + claim.getId(); |
|||
} |
|||
return () -> null; |
|||
} |
|||
} |
@ -1,27 +0,0 @@ |
|||
package com.dji.sample.component.websocket.config; |
|||
|
|||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
|||
import com.dji.sdk.websocket.WebSocketDefaultFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.context.annotation.Primary; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.web.socket.WebSocketHandler; |
|||
|
|||
/** |
|||
* |
|||
* @author sean.zhou |
|||
* @date 2021/11/16 |
|||
* @version 0.1 |
|||
*/ |
|||
@Component |
|||
@Primary |
|||
public class MyWebSocketFactory extends WebSocketDefaultFactory { |
|||
|
|||
@Autowired |
|||
private IWebSocketManageService webSocketManageService; |
|||
|
|||
@Override |
|||
public WebSocketHandler decorate(WebSocketHandler handler) { |
|||
return new MyWebSocketHandler(handler, webSocketManageService); |
|||
} |
|||
} |
@ -1,58 +0,0 @@ |
|||
package com.dji.sample.component.websocket.config; |
|||
|
|||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
|||
import com.dji.sdk.websocket.WebSocketDefaultHandler; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.socket.CloseStatus; |
|||
import org.springframework.web.socket.WebSocketHandler; |
|||
import org.springframework.web.socket.WebSocketMessage; |
|||
import org.springframework.web.socket.WebSocketSession; |
|||
|
|||
import java.security.Principal; |
|||
|
|||
/** |
|||
* |
|||
* @author sean.zhou |
|||
* @date 2021/11/16 |
|||
* @version 0.1 |
|||
*/ |
|||
@Slf4j |
|||
public class MyWebSocketHandler extends WebSocketDefaultHandler { |
|||
|
|||
private IWebSocketManageService webSocketManageService; |
|||
|
|||
MyWebSocketHandler(WebSocketHandler delegate, IWebSocketManageService webSocketManageService) { |
|||
super(delegate); |
|||
this.webSocketManageService = webSocketManageService; |
|||
} |
|||
|
|||
@Override |
|||
public void afterConnectionEstablished(WebSocketSession session) throws Exception { |
|||
Principal principal = session.getPrincipal(); |
|||
if (StringUtils.hasText(principal.getName())) { |
|||
webSocketManageService.put(principal.getName(), new MyConcurrentWebSocketSession(session)); |
|||
log.debug("{} is connected. ID: {}. WebSocketSession[current count: {}]", |
|||
principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); |
|||
return; |
|||
} |
|||
session.close(); |
|||
} |
|||
|
|||
@Override |
|||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { |
|||
Principal principal = session.getPrincipal(); |
|||
if (StringUtils.hasText(principal.getName())) { |
|||
webSocketManageService.remove(principal.getName(), session.getId()); |
|||
log.debug("{} is disconnected. ID: {}. WebSocketSession[current count: {}]", |
|||
principal.getName(), session.getId(), webSocketManageService.getConnectedCount()); |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { |
|||
log.debug("received message: {}", message.getPayload()); |
|||
} |
|||
|
|||
} |
@ -1,93 +0,0 @@ |
|||
package com.dji.sample.component.websocket.model; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 0.1 |
|||
* @date 2021/11/26 |
|||
*/ |
|||
public enum BizCodeEnum { |
|||
|
|||
DEVICE_ONLINE("device_online"), |
|||
|
|||
DEVICE_OFFLINE("device_offline"), |
|||
|
|||
DEVICE_UPDATE_TOPO("device_update_topo"), |
|||
|
|||
DEVICE_OSD("device_osd"), |
|||
|
|||
RC_OSD("gateway_osd"), |
|||
|
|||
DOCK_OSD("dock_osd"), |
|||
|
|||
MAP_ELEMENT_CREATE("map_element_create"), |
|||
|
|||
MAP_ELEMENT_UPDATE("map_element_update"), |
|||
|
|||
MAP_ELEMENT_DELETE("map_element_delete"), |
|||
|
|||
MAP_GROUP_REFRESH("map_group_refresh"), |
|||
|
|||
FLIGHT_TASK_PROGRESS("flighttask_progress"), |
|||
|
|||
DEVICE_HMS("device_hms"), |
|||
|
|||
DEVICE_REBOOT("device_reboot"), |
|||
|
|||
DRONE_OPEN("drone_open"), |
|||
|
|||
DRONE_CLOSE("drone_close"), |
|||
|
|||
DEVICE_CHECK("device_check"), |
|||
|
|||
DRONE_FORMAT("drone_format"), |
|||
|
|||
DEVICE_FORMAT("device_format"), |
|||
|
|||
COVER_OPEN("cover_open"), |
|||
|
|||
COVER_CLOSE("cover_close"), |
|||
|
|||
PUTTER_OPEN("putter_open"), |
|||
|
|||
PUTTER_CLOSE("putter_close"), |
|||
|
|||
CHARGE_OPEN("charge_open"), |
|||
|
|||
CHARGE_CLOSE("charge_close"), |
|||
|
|||
FILE_UPLOAD_CALLBACK("file_upload_callback"), |
|||
|
|||
FILE_UPLOAD_PROGRESS("fileupload_progress"), |
|||
|
|||
OTA_PROGRESS("ota_progress"), |
|||
|
|||
HIGHEST_PRIORITY_UPLOAD_FLIGHT_TASK_MEDIA("highest_priority_upload_flighttask_media"), |
|||
|
|||
CONTROL_SOURCE_CHANGE("control_source_change"), |
|||
|
|||
FLY_TO_POINT_PROGRESS("fly_to_point_progress"), |
|||
|
|||
TAKE_OFF_TO_POINT_PROGRESS("takeoff_to_point_progress"), |
|||
|
|||
DRC_STATUS_NOTIFY("drc_status_notify"), |
|||
|
|||
JOYSTICK_INVALID_NOTIFY("joystick_invalid_notify"), |
|||
|
|||
FLIGHT_AREAS_SYNC_PROGRESS("flight_areas_sync_progress"), |
|||
|
|||
FLIGHT_AREAS_DRONE_LOCATION("flight_areas_drone_location"), |
|||
|
|||
FLIGHT_AREAS_UPDATE("flight_areas_update"), |
|||
|
|||
; |
|||
|
|||
private String code; |
|||
|
|||
BizCodeEnum(String code) { |
|||
this.code = code; |
|||
} |
|||
|
|||
public String getCode() { |
|||
return code; |
|||
} |
|||
} |
@ -1,23 +0,0 @@ |
|||
package com.dji.sample.component.websocket.service; |
|||
|
|||
import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; |
|||
|
|||
import java.util.Collection; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.0 |
|||
* @date 2022/4/25 |
|||
*/ |
|||
public interface IWebSocketManageService { |
|||
|
|||
void put(String key, MyConcurrentWebSocketSession val); |
|||
|
|||
void remove(String key, String sessionId); |
|||
|
|||
Collection<MyConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId); |
|||
|
|||
Collection<MyConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType); |
|||
|
|||
Long getConnectedCount(); |
|||
} |
@ -1,32 +0,0 @@ |
|||
package com.dji.sample.component.websocket.service; |
|||
|
|||
import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; |
|||
import com.dji.sdk.websocket.WebSocketMessageResponse; |
|||
|
|||
import java.util.Collection; |
|||
|
|||
/** |
|||
* @author sean.zhou |
|||
* @date 2021/11/24 |
|||
* @version 0.1 |
|||
*/ |
|||
public interface IWebSocketMessageService { |
|||
|
|||
/** |
|||
* Send a message to the specific connection. |
|||
* @param session A WebSocket connection object |
|||
* @param message message |
|||
*/ |
|||
void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message); |
|||
|
|||
/** |
|||
* Send the same message to specific connection. |
|||
* @param sessions A collection of WebSocket connection objects. |
|||
* @param message message |
|||
*/ |
|||
void sendBatch(Collection<MyConcurrentWebSocketSession> sessions, WebSocketMessageResponse message); |
|||
|
|||
void sendBatch(String workspaceId, Integer userType, String bizCode, Object data); |
|||
|
|||
void sendBatch(String workspaceId, String bizCode, Object data); |
|||
} |
@ -1,86 +0,0 @@ |
|||
package com.dji.sample.component.websocket.service.impl; |
|||
|
|||
import com.dji.sample.component.redis.RedisConst; |
|||
import com.dji.sample.component.redis.RedisOpsUtils; |
|||
import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; |
|||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
|||
import com.dji.sample.manage.model.enums.UserTypeEnum; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.Collections; |
|||
import java.util.Objects; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* @author sean |
|||
* @version 1.0 |
|||
* @date 2022/4/25 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class WebSocketManageServiceImpl implements IWebSocketManageService { |
|||
|
|||
private static final ConcurrentHashMap<String, MyConcurrentWebSocketSession> SESSIONS = new ConcurrentHashMap<>(16); |
|||
|
|||
@Override |
|||
public void put(String key, MyConcurrentWebSocketSession val) { |
|||
String[] name = key.split("/"); |
|||
if (name.length != 3) { |
|||
log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); |
|||
return; |
|||
} |
|||
String sessionId = val.getId(); |
|||
String workspaceKey = RedisConst.WEBSOCKET_PREFIX + name[0]; |
|||
String userTypeKey = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])).getDesc(); |
|||
RedisOpsUtils.hashSet(workspaceKey, sessionId, name[2]); |
|||
RedisOpsUtils.hashSet(userTypeKey, sessionId, name[2]); |
|||
SESSIONS.put(sessionId, val); |
|||
RedisOpsUtils.expireKey(workspaceKey, RedisConst.WEBSOCKET_ALIVE_SECOND); |
|||
RedisOpsUtils.expireKey(userTypeKey, RedisConst.WEBSOCKET_ALIVE_SECOND); |
|||
} |
|||
|
|||
@Override |
|||
public void remove(String key, String sessionId) { |
|||
String[] name = key.split("/"); |
|||
if (name.length != 3) { |
|||
log.debug("The key is out of format. [{workspaceId}/{userType}/{userId}]"); |
|||
return; |
|||
} |
|||
RedisOpsUtils.hashDel(RedisConst.WEBSOCKET_PREFIX + name[0], new String[] {sessionId}); |
|||
RedisOpsUtils.hashDel(RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(Integer.parseInt(name[1])).getDesc(), new String[] {sessionId}); |
|||
SESSIONS.remove(sessionId); |
|||
} |
|||
|
|||
@Override |
|||
public Collection<MyConcurrentWebSocketSession> getValueWithWorkspace(String workspaceId) { |
|||
if (!StringUtils.hasText(workspaceId)) { |
|||
return Collections.emptySet(); |
|||
} |
|||
String key = RedisConst.WEBSOCKET_PREFIX + workspaceId; |
|||
|
|||
return RedisOpsUtils.hashKeys(key) |
|||
.stream() |
|||
.map(SESSIONS::get) |
|||
.filter(Objects::nonNull) |
|||
.collect(Collectors.toSet()); |
|||
} |
|||
|
|||
@Override |
|||
public Collection<MyConcurrentWebSocketSession> getValueWithWorkspaceAndUserType(String workspaceId, Integer userType) { |
|||
String key = RedisConst.WEBSOCKET_PREFIX + UserTypeEnum.find(userType).getDesc(); |
|||
return RedisOpsUtils.hashKeys(key) |
|||
.stream() |
|||
.map(SESSIONS::get) |
|||
.filter(getValueWithWorkspace(workspaceId)::contains) |
|||
.collect(Collectors.toSet()); |
|||
} |
|||
|
|||
@Override |
|||
public Long getConnectedCount() { |
|||
return SESSIONS.mappingCount(); |
|||
} |
|||
} |
@ -1,99 +0,0 @@ |
|||
package com.dji.sample.component.websocket.service.impl; |
|||
|
|||
import com.dji.sample.component.websocket.config.MyConcurrentWebSocketSession; |
|||
import com.dji.sample.component.websocket.service.IWebSocketManageService; |
|||
import com.dji.sample.component.websocket.service.IWebSocketMessageService; |
|||
import com.dji.sdk.websocket.WebSocketMessageResponse; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.socket.TextMessage; |
|||
|
|||
import java.io.IOException; |
|||
import java.util.Collection; |
|||
import java.util.Objects; |
|||
|
|||
/** |
|||
* @author sean.zhou |
|||
* @version 0.1 |
|||
* @date 2021/11/24 |
|||
*/ |
|||
@Service |
|||
@Slf4j |
|||
public class WebSocketMessageServiceImpl implements IWebSocketMessageService { |
|||
|
|||
@Autowired |
|||
private ObjectMapper mapper; |
|||
|
|||
@Autowired |
|||
private IWebSocketManageService webSocketManageService; |
|||
|
|||
@Override |
|||
public void sendMessage(MyConcurrentWebSocketSession session, WebSocketMessageResponse message) { |
|||
if (session == null) { |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
if (!session.isOpen()) { |
|||
session.close(); |
|||
log.debug("This session is closed."); |
|||
return; |
|||
} |
|||
|
|||
|
|||
session.sendMessage(new TextMessage(mapper.writeValueAsBytes(message))); |
|||
} catch (IOException e) { |
|||
log.info("Failed to publish the message. {}", message.toString()); |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void sendBatch(Collection<MyConcurrentWebSocketSession> sessions, WebSocketMessageResponse message) { |
|||
if (sessions.isEmpty()) { |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
|
|||
TextMessage data = new TextMessage(mapper.writeValueAsBytes(message)); |
|||
|
|||
for (MyConcurrentWebSocketSession session : sessions) { |
|||
if (!session.isOpen()) { |
|||
session.close(); |
|||
log.debug("This session is closed."); |
|||
return; |
|||
} |
|||
session.sendMessage(data); |
|||
} |
|||
|
|||
} catch (IOException e) { |
|||
log.info("Failed to publish the message. {}", message.toString()); |
|||
|
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void sendBatch(String workspaceId, Integer userType, String bizCode, Object data) { |
|||
if (!StringUtils.hasText(workspaceId)) { |
|||
throw new RuntimeException("工作区ID不存在。"); |
|||
} |
|||
Collection<MyConcurrentWebSocketSession> sessions = Objects.isNull(userType) ? |
|||
webSocketManageService.getValueWithWorkspace(workspaceId) : |
|||
webSocketManageService.getValueWithWorkspaceAndUserType(workspaceId, userType); |
|||
|
|||
this.sendBatch(sessions, new WebSocketMessageResponse() |
|||
.setData(Objects.requireNonNullElse(data, "")) |
|||
.setTimestamp(System.currentTimeMillis()) |
|||
.setBizCode(bizCode)); |
|||
} |
|||
|
|||
@Override |
|||
public void sendBatch(String workspaceId, String bizCode, Object data) { |
|||
this.sendBatch(workspaceId, null, bizCode, data); |
|||
} |
|||
} |
@ -1,40 +0,0 @@ |
|||
package com.dji.sample.configuration.mvc; |
|||
|
|||
import com.dji.sample.component.AuthInterceptor; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
@Configuration |
|||
public class GlobalMVCConfigurer implements WebMvcConfigurer { |
|||
|
|||
@Autowired |
|||
private AuthInterceptor authInterceptor; |
|||
|
|||
private static List<String> excludePaths = new ArrayList<>(); |
|||
|
|||
@Value("${url.manage.prefix}") |
|||
private String managePrefix; |
|||
|
|||
@Value("${url.manage.version}") |
|||
private String manageVersion; |
|||
|
|||
|
|||
@Override |
|||
public void addInterceptors(InterceptorRegistry registry) { |
|||
// Exclude the login interface.
|
|||
excludePaths.add("/" + managePrefix + manageVersion + "/login"); |
|||
excludePaths.add("/" + managePrefix + manageVersion + "/token/refresh"); |
|||
excludePaths.add("/swagger-ui.html"); |
|||
excludePaths.add("/swagger-ui/**"); |
|||
excludePaths.add("/v3/**"); |
|||
excludePaths.add("/ui/**"); |
|||
// Intercept for all request interfaces.
|
|||
registry.addInterceptor(authInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths); |
|||
} |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue