REM:
1. 增加前端信任主机token,IP地址配置项
2. 增加前端接口拦截器,进行授权校验
3. 增加对多个IP采用同样配置进行处置接口
4. 合并接口授权校验配置类
5. 增加启动处置任务接口返回数据信息
6. 启动处置任务增加检查是否支持该IP/处置类型
7. 增加IP数组校验器
8. 重命名device_list接口为deviceList
9. 修正代码重构后某些测试用的数据类型
This commit is contained in:
HuangXin 2020-09-01 19:50:00 +08:00
parent 4d5227c1fb
commit ae289ef9e0
22 changed files with 511 additions and 81 deletions

View File

@ -22,6 +22,10 @@ auth.token-timeout-minute=30
# 安全配置 # 安全配置
crypto.security-protocol-type=0 crypto.security-protocol-type=0
crypto.aes-key="hkoUV5ZWh0q1jSxMnpjovVn19Qg99HY6DD40" crypto.aes-key=hkoUV5ZWh0q1jSxMnpjovVn19Qg99HY6DD40
crypto.des-key="P3mq9iSIvQcvfyfdWR8sAnfAadO" crypto.des-key=P3mq9iSIvQcvfyfdWR8sAnfAadO
#信任主机配置
trust.auth-host-token=165B2AA40395fA27278E59eEd4DD5EA490DA175344DE2673A5B17D3760E12F0
trust.auth-hosts=127.0.0.12,::1

View File

@ -1,5 +1,7 @@
package com.dispose.common; package com.dispose.common;
import java.util.HashMap;
/** /**
* The type Auth config value. * The type Auth config value.
* *
@ -31,4 +33,9 @@ public class AuthConfigValue {
* The constant MYSQL_REGEX_CHARS. * The constant MYSQL_REGEX_CHARS.
*/ */
public static final String MYSQL_REGEX_CHARS = "^((?!(--|\\s|\\*|%|\\+|'|;])).)*$"; public static final String MYSQL_REGEX_CHARS = "^((?!(--|\\s|\\*|%|\\+|'|;])).)*$";
/**
* The constant TRUST_INFO_CACHE.
*/
public static volatile HashMap<String, Long> TRUST_INFO_CACHE = new HashMap<>();
} }

View File

@ -161,6 +161,21 @@ public enum ErrorCode {
*/ */
ERR_DATABASE(35, "操作数据库失败"), ERR_DATABASE(35, "操作数据库失败"),
/**
* The Err ipnodevice.
*/
ERR_IPNODEVICE(36, "找不到处置该IP的设备"),
/**
* Err untrusthost error code.
*/
ERR_UNTRUSTHOST(37, "未经授权的客户端"),
/**
* Err untrusttoken error code.
*/
ERR_UNTRUSTTOKEN(37, "未经授权的Token"),
/** /**
* The Err decrypt base 64. * The Err decrypt base 64.
*/ */
@ -195,11 +210,11 @@ public enum ErrorCode {
ERR_ENCRYPT_UNKNOWN(107, "不支持的加密算法"), ERR_ENCRYPT_UNKNOWN(107, "不支持的加密算法"),
/** /**
* Err json encode error code. * The Err json encode.
*/ */
ERR_JSON_ENCODE(108, "Json 序列号错误"), ERR_JSON_ENCODE(108, "Json 序列号错误"),
/** /**
* Err json decode error code. * The Err json decode.
*/ */
ERR_JSON_DECODE(109, "Json 反序列化错误"), ERR_JSON_DECODE(109, "Json 反序列化错误"),
; ;

View File

@ -1,11 +1,15 @@
package com.dispose.config; package com.dispose.config;
import com.dispose.common.AuthConfigValue; import com.dispose.common.AuthConfigValue;
import com.dispose.interceptor.TokenInterceptor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Optional; import java.util.Optional;
@ -20,7 +24,7 @@ import java.util.Optional;
@Component @Component
@ConfigurationProperties(prefix = "auth") @ConfigurationProperties(prefix = "auth")
@Configuration @Configuration
public class AuthConfigure { public class AuthConfigure implements WebMvcConfigurer {
/** /**
* The Token timeout minute. * The Token timeout minute.
*/ */
@ -39,4 +43,21 @@ public class AuthConfigure {
AuthConfigValue.TOKEN_EXPIRED_TIME_MS = Optional.ofNullable(tokenTimeoutMinute).orElse((long) 30 * 60 * 1000); AuthConfigValue.TOKEN_EXPIRED_TIME_MS = Optional.ofNullable(tokenTimeoutMinute).orElse((long) 30 * 60 * 1000);
AuthConfigValue.VERIFY_REQUEST_TOKEN = Optional.ofNullable(verifyRequestToken).orElse(true); AuthConfigValue.VERIFY_REQUEST_TOKEN = Optional.ofNullable(verifyRequestToken).orElse(true);
} }
@Bean
public TokenInterceptor initAuthInterceptor(){
return new TokenInterceptor();
}
/**
* Add interceptors.
*
* @param registry the registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册需要检查token的控制器接口
registry.addInterceptor(initAuthInterceptor()).addPathPatterns("/information/**");
registry.addInterceptor(initAuthInterceptor()).addPathPatterns("/task/**");
}
} }

View File

@ -1,37 +0,0 @@
package com.dispose.config;
import com.dispose.interceptor.TokenInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* The type Auth token config.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
@Configuration
public class AuthTokenConfig implements WebMvcConfigurer {
/**
* Init auth interceptor token interceptor.
*
* @return the token interceptor
*/
@Bean
public TokenInterceptor initAuthInterceptor(){
return new TokenInterceptor();
}
/**
* Add interceptors.
*
* @param registry the registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册需要检查token的控制器接口
registry.addInterceptor(initAuthInterceptor()).addPathPatterns("/information/**");
registry.addInterceptor(initAuthInterceptor()).addPathPatterns("/task/**");
}
}

View File

@ -0,0 +1,74 @@
package com.dispose.config;
import com.dispose.common.AuthConfigValue;
import com.dispose.common.Helper;
import com.dispose.interceptor.TrustHostInterceptor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.PostConstruct;
import java.util.Optional;
/**
* The type Trust host config.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "trust")
@Configuration
public class TrustHostConfig implements WebMvcConfigurer {
/**
* The Auth host token.
*/
private String[] authHostToken;
/**
* The Auth hosts.
*/
private String[] authHosts;
/**
* Init global value.
*/
@PostConstruct
private void initGlobalValue() {
for (String s : Optional.ofNullable(authHostToken).orElse(new String[]{""})) {
AuthConfigValue.TRUST_INFO_CACHE.put(s, System.currentTimeMillis());
}
for (String s : Optional.ofNullable(authHosts).orElse(new String[]{"127.0.0.1"})) {
AuthConfigValue.TRUST_INFO_CACHE.put(Helper.ipAddressNormalize(s), System.currentTimeMillis());
}
}
/**
* Init front view interceptor trust host interceptor.
*
* @return the trust host interceptor
*/
@Bean
public TrustHostInterceptor initFrontViewInterceptor() {
return new TrustHostInterceptor();
}
/**
* Add interceptors.
*
* @param registry the registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册需要检查token的控制器接口
registry.addInterceptor(initFrontViewInterceptor()).addPathPatterns("/frontview/**");
}
}

View File

@ -238,7 +238,7 @@ public class DisposeDeviceManagerController {
* @param mr the mr * @param mr the mr
* @return the all dispose device * @return the all dispose device
*/ */
@PostMapping("/device_list") @PostMapping("/deviceList")
@ResponseBody @ResponseBody
@ApiOperation("获取处置能力节点") @ApiOperation("获取处置能力节点")
public ProtocolRespDTO<? extends BaseRespStatus> getAllDisposeDevice( public ProtocolRespDTO<? extends BaseRespStatus> getAllDisposeDevice(

View File

@ -7,13 +7,13 @@ import com.dispose.common.DisposeConfigValue;
import com.dispose.common.ErrorCode; import com.dispose.common.ErrorCode;
import com.dispose.common.Helper; import com.dispose.common.Helper;
import com.dispose.common.NetflowDirection; import com.dispose.common.NetflowDirection;
import com.dispose.pojo.dto.protocol.base.BaseIdResp;
import com.dispose.pojo.dto.protocol.base.BaseRespStatus; import com.dispose.pojo.dto.protocol.base.BaseRespStatus;
import com.dispose.pojo.dto.protocol.base.IdArraysReq; import com.dispose.pojo.dto.protocol.base.IdArraysReq;
import com.dispose.pojo.dto.protocol.base.ProtocolReqDTO; import com.dispose.pojo.dto.protocol.base.ProtocolReqDTO;
import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO; import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO;
import com.dispose.pojo.dto.protocol.task.TaskStartReq; import com.dispose.pojo.dto.protocol.task.TaskStartReq;
import com.dispose.pojo.dto.protocol.task.TaskStopResp; import com.dispose.pojo.dto.protocol.task.TaskStartRsp;
import com.dispose.pojo.dto.protocol.task.TaskStopRsp;
import com.dispose.pojo.entity.DeviceTask; import com.dispose.pojo.entity.DeviceTask;
import com.dispose.pojo.entity.DisposeTask; import com.dispose.pojo.entity.DisposeTask;
import com.dispose.pojo.po.MulReturnType; import com.dispose.pojo.po.MulReturnType;
@ -84,7 +84,7 @@ public class DisposeTaskController {
@NotNull @RequestHeader HttpHeaders headers) { @NotNull @RequestHeader HttpHeaders headers) {
TaskStartReq req = mr.getMsgContent(); TaskStartReq req = mr.getMsgContent();
// 处置任务参数 // 处置任务参数
DisposeTask task = DisposeTask.builder() DisposeTask task = DisposeTask.builder()
.deviceId(Long.parseLong(Optional.ofNullable(req.getId()).orElse("-1"))) .deviceId(Long.parseLong(Optional.ofNullable(req.getId()).orElse("-1")))
.accountId(userAccountService.getUserIdByAuthHead(Objects.requireNonNull(headers.get("Authorization")).get(0))) .accountId(userAccountService.getUserIdByAuthHead(Objects.requireNonNull(headers.get("Authorization")).get(0)))
@ -101,22 +101,86 @@ public class DisposeTaskController {
.build(); .build();
// 创建处置任务 // 创建处置任务
MulReturnType<ErrorCode, Long> ret = disposeTaskService.createTask(task); MulReturnType<ErrorCode, DisposeTask> ret = disposeTaskService.createTask(task);
// 启动任务失败
if (ret.getFirstParam() != ErrorCode.ERR_OK) {
log.error("Start task failed, error: {}", ret.getFirstParam().getMsg());
return ProtocolRespDTO.result(ret.getFirstParam());
}
// 设置返回消息 // 设置返回消息
BaseIdResp rspInfo = new BaseIdResp(); TaskStartRsp rspInfo = TaskStartRsp.builder()
.disposeIp(task.getDisposeIp())
.build();
rspInfo.setTaskId(ret.getSecondParam().toString());
rspInfo.setStatus(ret.getFirstParam().getCode()); rspInfo.setStatus(ret.getFirstParam().getCode());
rspInfo.setMessage(new String[]{ret.getFirstParam().getMsg()}); rspInfo.setMessage(new String[]{ret.getFirstParam().getMsg()});
return ProtocolRespDTO.result(ErrorCode.ERR_OK, rspInfo); if (ret.getFirstParam() != ErrorCode.ERR_OK) {
log.error("Start task failed, error: {}", ret.getFirstParam().getMsg());
if (ret.getFirstParam() != ErrorCode.ERR_TASKRUNNING) {
return ProtocolRespDTO.result(ret.getFirstParam(), rspInfo);
}
}
rspInfo.setTaskId(ret.getSecondParam().getId().toString());
rspInfo.setExpireTime(ret.getSecondParam().getPlanEndTime());
return ProtocolRespDTO.result(ret.getFirstParam(), rspInfo);
}
@PostMapping("/startMulIp")
@ResponseBody
@ApiOperation("启动处置任务")
public ProtocolRespDTO<List<TaskStartRsp>> startTaskMulIp(@Validated(ValidGroups.TaskStartMulReqValid.class)
@RequestBody ProtocolReqDTO<TaskStartReq> mr,
@NotNull @RequestHeader HttpHeaders headers) {
TaskStartReq req = mr.getMsgContent();
Long devId = Long.parseLong(Optional.ofNullable(req.getId()).orElse("-1"));
Long aId = userAccountService.getUserIdByAuthHead(Objects.requireNonNull(headers.get("Authorization")).get(0));
DisposeCapacityType capType = CommonEnumHandler.codeOf(DisposeCapacityType.class, req.getType());
String endTime = String.valueOf(req.getDisposeTime());
NetflowDirection netDir = CommonEnumHandler.codeOf(NetflowDirection.class,
Optional.ofNullable(req.getFlowDirection()).orElse(2));
Long attackType = DDoSAttackType.getTypeMaskFromAttackType(Optional.ofNullable(req.getAttackType())
.orElse(new Integer[]{DDoSAttackType.ALL_ATTACKS.getValue()}));
Integer flowBand = Optional.ofNullable(req.getFlowBandwidth())
.orElse(DisposeConfigValue.DEFAULT_DISPOSE_BANDWIDTH);
List<TaskStartRsp> rspList = new ArrayList<>();
for (String ip : req.getMulDisposeIp()) {
// 构造处置任务参数
DisposeTask task = DisposeTask.builder()
.deviceId(devId)
.accountId(aId)
.disposeCapacity(capType)
.disposeIp(Helper.ipAddressNormalize(ip))
.planEndTime(endTime)
.flowDirection(netDir)
.attackType(attackType)
.flowBandWidth(flowBand)
.build();
// 创建处置任务
MulReturnType<ErrorCode, DisposeTask> ret = disposeTaskService.createTask(task);
// 设置返回消息
TaskStartRsp rspInfo = TaskStartRsp.builder()
.disposeIp(ip)
.build();
// 启动任务成功
if (ret.getFirstParam() == ErrorCode.ERR_OK ||
ret.getFirstParam() == ErrorCode.ERR_TASKRUNNING) {
rspInfo.setTaskId(ret.getSecondParam().getId().toString());
rspInfo.setExpireTime(ret.getSecondParam().getPlanEndTime());
}
rspInfo.setStatus(ret.getFirstParam().getCode());
rspInfo.setMessage(new String[]{ret.getFirstParam().getMsg()});
rspList.add(rspInfo);
}
return ProtocolRespDTO.result(ErrorCode.ERR_OK, rspList);
} }
/** /**
@ -132,13 +196,13 @@ public class DisposeTaskController {
@RequestBody ProtocolReqDTO<IdArraysReq> mr) { @RequestBody ProtocolReqDTO<IdArraysReq> mr) {
// 记录多个任务停止信息 // 记录多个任务停止信息
List<TaskStopResp> rspList = new ArrayList<>(); List<TaskStopRsp> rspList = new ArrayList<>();
for (String tId : mr.getMsgContent().getTaskId()) { for (String tId : mr.getMsgContent().getTaskId()) {
// 停止处置任务 // 停止处置任务
MulReturnType<ErrorCode, DisposeTask> ret = disposeTaskService.stopTask(Long.parseLong(tId)); MulReturnType<ErrorCode, DisposeTask> ret = disposeTaskService.stopTask(Long.parseLong(tId));
TaskStopResp rspInfo = TaskStopResp.builder().build(); TaskStopRsp rspInfo = TaskStopRsp.builder().build();
// 停止成功 // 停止成功
if (ret.getFirstParam() == ErrorCode.ERR_OK) { if (ret.getFirstParam() == ErrorCode.ERR_OK) {

View File

@ -0,0 +1,69 @@
package com.dispose.interceptor;
import com.dispose.common.AuthConfigValue;
import com.dispose.common.ErrorCode;
import com.dispose.common.Helper;
import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import reactor.util.annotation.NonNull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* The type Trust host interceptor.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
@Slf4j
public class TrustHostInterceptor implements HandlerInterceptor {
/**
* Pre handle boolean.
*
* @param request the request
* @param response the response
* @param handler the handler
* @return the boolean
*/
@Override
public boolean preHandle(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler) throws IOException {
ErrorCode err;
// 获取访问接口的客户端IP
String remoteIp = request.getRemoteAddr();
// 判断该IP是否在信任列表内
if (AuthConfigValue.TRUST_INFO_CACHE.containsKey(Helper.ipAddressNormalize(remoteIp))) {
// 提取header中的Authorization字段里面的token值
String token = request.getHeader("Authorization");
if (token != null && token.length() > 0) {
// 判断token是否在信任列表中
if(AuthConfigValue.TRUST_INFO_CACHE.containsKey(token)) {
return true;
} else {
err = ErrorCode.ERR_UNTRUSTTOKEN;
log.error("http request token [{}] is not trust", token);
}
} else {
err = ErrorCode.ERR_MISSAUTHHEAD;
log.error("Http request token [{}] is does not trust token", token);
}
} else {
err = ErrorCode.ERR_UNTRUSTHOST;
log.error("Remote host {} not trust", remoteIp);
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(new ObjectMapper().writeValueAsString(ProtocolRespDTO.result(err)));
return false;
}
}

View File

@ -1,6 +1,7 @@
package com.dispose.pojo.dto.protocol.task; package com.dispose.pojo.dto.protocol.task;
import com.dispose.validation.group.ValidGroups; import com.dispose.validation.group.ValidGroups;
import com.dispose.validation.valids.ValidArrayIpAddr;
import com.dispose.validation.valids.ValidDDosAttackType; import com.dispose.validation.valids.ValidDDosAttackType;
import com.dispose.validation.valids.ValidIpAddr; import com.dispose.validation.valids.ValidIpAddr;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -32,10 +33,10 @@ public class TaskStartReq {
/** /**
* The Type. * The Type.
*/ */
@NotNull(message = "type 处置类型不能为空", groups = ValidGroups.TaskStartReqValid.class) @NotNull(message = "type 处置类型不能为空", groups = ValidGroups.TaskStartReqCommonValid.class)
@Range(min = 0, max = 3, @Range(min = 0, max = 3,
message = "type 字段取值为 [0, 3]", message = "type 字段取值为 [0, 3]",
groups = ValidGroups.TaskStartReqValid.class) groups = ValidGroups.TaskStartReqCommonValid.class)
private Integer type; private Integer type;
/** /**
* The Dispose ip. * The Dispose ip.
@ -43,24 +44,32 @@ public class TaskStartReq {
@NotBlank(message = "disposeIp 处置IP地址不能为空", groups = ValidGroups.TaskStartReqValid.class) @NotBlank(message = "disposeIp 处置IP地址不能为空", groups = ValidGroups.TaskStartReqValid.class)
@ValidIpAddr(message = "disposeIp Ip地址格式错误", groups = ValidGroups.TaskStartReqValid.class) @ValidIpAddr(message = "disposeIp Ip地址格式错误", groups = ValidGroups.TaskStartReqValid.class)
private String disposeIp; private String disposeIp;
/**
* The Mul dispose ip.
*/
@NotNull(message = "mulDisposeIp 处置IP地址不能为空", groups = ValidGroups.TaskStartMulReqValid.class)
@ValidArrayIpAddr(message = "mulDisposeIp Ip地址格式错误", groups = ValidGroups.TaskStartMulReqValid.class)
@Size(min = 1, max = 255, message = "mulDisposeIp 必须包含 1-255 个元素",
groups = ValidGroups.TaskStartMulReqValid.class)
private String[] mulDisposeIp;
/** /**
* The Dispose time. * The Dispose time.
*/ */
@NotNull(message = "disposeTime 处置时间不能为空", groups = ValidGroups.TaskStartReqValid.class) @NotNull(message = "disposeTime 处置时间不能为空", groups = ValidGroups.TaskStartReqCommonValid.class)
private Integer disposeTime; private Integer disposeTime;
/** /**
* The Flow direction. * The Flow direction.
*/ */
@Range(min = 0, max = 2, @Range(min = 0, max = 2,
message = "flowDirection 字段取值为 [0, 2]", message = "flowDirection 字段取值为 [0, 2]",
groups = ValidGroups.TaskStartReqValid.class) groups = ValidGroups.TaskStartReqCommonValid.class)
private Integer flowDirection; private Integer flowDirection;
/** /**
* The Attack type. * The Attack type.
*/ */
@ValidDDosAttackType(message = "attackType 攻击类型参数错误", groups = ValidGroups.TaskStartReqValid.class) @ValidDDosAttackType(message = "attackType 攻击类型参数错误", groups = ValidGroups.TaskStartReqCommonValid.class)
@Size(min = 1, message = "attackType 必须指定最少一种攻击类型", @Size(min = 1, message = "attackType 必须指定最少一种攻击类型",
groups = ValidGroups.ProtocolCommonValid.class) groups = ValidGroups.TaskStartReqCommonValid.class)
private Integer[] attackType; private Integer[] attackType;
/** /**
* The Flow bandwidth. * The Flow bandwidth.

View File

@ -0,0 +1,31 @@
package com.dispose.pojo.dto.protocol.task;
import com.dispose.pojo.dto.protocol.base.BaseIdResp;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* The type Task start rsp.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@AllArgsConstructor
@JsonPropertyOrder({"taskId", "disposeIp", "expireTime", "status", "message"})
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TaskStartRsp extends BaseIdResp {
/**
* The Dispose ip.
*/
private String disposeIp;
/**
* The Expire time.
*/
private String expireTime;
}

View File

@ -21,7 +21,7 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
@JsonPropertyOrder({"taskId", "disposeDevice", "type", "disposeIp", "leftTime", "status", "message"}) @JsonPropertyOrder({"taskId", "disposeDevice", "type", "disposeIp", "leftTime", "status", "message"})
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public class TaskStopResp extends BaseIdResp { public class TaskStopRsp extends BaseIdResp {
/** /**
* The Dispose device. * The Dispose device.

View File

@ -1,5 +1,6 @@
package com.dispose.service; package com.dispose.service;
import com.dispose.common.DisposeCapacityType;
import com.dispose.common.ErrorCode; import com.dispose.common.ErrorCode;
import com.dispose.pojo.entity.DisposeDevice; import com.dispose.pojo.entity.DisposeDevice;
import com.dispose.pojo.po.AbilityInfo; import com.dispose.pojo.po.AbilityInfo;
@ -43,4 +44,14 @@ public interface DisposeAbilityRouterService {
* @return the error code * @return the error code
*/ */
ErrorCode addDisposeAbilityDevice(DisposeDevice dev); ErrorCode addDisposeAbilityDevice(DisposeDevice dev);
/**
* Verify dispose capacity error code.
*
* @param deviceId the device id
* @param disposeIp the dispose ip
* @param capacityType the capacity type
* @return the error code
*/
ErrorCode verifyDisposeCapacity(Long deviceId, String disposeIp, DisposeCapacityType capacityType);
} }

View File

@ -17,7 +17,7 @@ public interface DisposeTaskService {
* @param task the task * @param task the task
* @return the mul return type * @return the mul return type
*/ */
MulReturnType<ErrorCode, Long> createTask(DisposeTask task); MulReturnType<ErrorCode, DisposeTask> createTask(DisposeTask task);
/** /**
* Stop task mul return type. * Stop task mul return type.

View File

@ -4,6 +4,7 @@ import com.dispose.ability.DisposeAbility;
import com.dispose.ability.impl.DpTechAbilityImpl; import com.dispose.ability.impl.DpTechAbilityImpl;
import com.dispose.ability.impl.HaoHanAbilityImpl; import com.dispose.ability.impl.HaoHanAbilityImpl;
import com.dispose.ability.impl.VirtualAbilityImpl; import com.dispose.ability.impl.VirtualAbilityImpl;
import com.dispose.common.DisposeCapacityType;
import com.dispose.common.ErrorCode; import com.dispose.common.ErrorCode;
import com.dispose.common.HttpType; import com.dispose.common.HttpType;
import com.dispose.manager.DisposeDeviceManager; import com.dispose.manager.DisposeDeviceManager;
@ -132,6 +133,36 @@ public class DisposeAbilityRouterServiceImpl implements DisposeAbilityRouterServ
return ErrorCode.ERR_OK; return ErrorCode.ERR_OK;
} }
/**
* Verify dispose capacity error code.
*
* @param deviceId the device id
* @param disposeIp the dispose ip
* @param capacityType the capacity type
* @return the error code
*/
@Override
public ErrorCode verifyDisposeCapacity(Long deviceId, String disposeIp, DisposeCapacityType capacityType) {
if (getAllAbilityDevices().stream()
.noneMatch(f -> deviceId == -1 || f.getDev().getId().equals(deviceId))) {
return ErrorCode.ERR_NOSUCHDEVICE;
}
if(getAllAbilityDevices().stream()
.noneMatch(c -> c.getDev().getDevCapacity().stream()
.anyMatch(m -> m.getCapacityType() == capacityType))) {
return ErrorCode.ERR_NOSUCHTYPE;
}
if(getAllAbilityDevices().stream()
.noneMatch(c -> c.getDb().isCarryProtectIp(disposeIp))) {
return ErrorCode.ERR_IPNODEVICE;
}
return ErrorCode.ERR_OK;
}
/** /**
* Gets ability device hash key. * Gets ability device hash key.
* *

View File

@ -5,6 +5,7 @@ import com.dispose.common.ErrorCode;
import com.dispose.manager.DisposeTaskManager; import com.dispose.manager.DisposeTaskManager;
import com.dispose.pojo.entity.DisposeTask; import com.dispose.pojo.entity.DisposeTask;
import com.dispose.pojo.po.MulReturnType; import com.dispose.pojo.po.MulReturnType;
import com.dispose.service.DisposeAbilityRouterService;
import com.dispose.service.DisposeTaskService; import com.dispose.service.DisposeTaskService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,6 +24,9 @@ public class DisposeTaskServiceImpl implements DisposeTaskService {
@Resource @Resource
DisposeTaskManager disposeTaskManager; DisposeTaskManager disposeTaskManager;
@Resource
DisposeAbilityRouterService disposeAbilityRouterService;
/** /**
* Create task mul return type. * Create task mul return type.
* *
@ -30,15 +34,24 @@ public class DisposeTaskServiceImpl implements DisposeTaskService {
* @return the mul return type * @return the mul return type
*/ */
@Override @Override
public MulReturnType<ErrorCode, Long> createTask(DisposeTask task) { public MulReturnType<ErrorCode, DisposeTask> createTask(DisposeTask task) {
DisposeTask exitTask = disposeTaskManager.getDisposeTask(task.getDeviceId(), DisposeTask exitTask = disposeTaskManager.getDisposeTask(task.getDeviceId(),
task.getDisposeIp(), task.getDisposeCapacity()); task.getDisposeIp(), task.getDisposeCapacity());
if (exitTask != null) { if (exitTask != null) {
return new MulReturnType<>(ErrorCode.ERR_TASKRUNNING, exitTask.getId()); return new MulReturnType<>(ErrorCode.ERR_TASKRUNNING, exitTask);
} }
return new MulReturnType<>(disposeTaskManager.addDisposeTask(task), task.getId()); ErrorCode err = disposeAbilityRouterService.verifyDisposeCapacity(
task.getDeviceId(), task.getDisposeIp(), task.getDisposeCapacity()
);
if(err != ErrorCode.ERR_OK) {
return new MulReturnType<>(err, task);
}
return new MulReturnType<>(disposeTaskManager.addDisposeTask(task),
disposeTaskManager.getDisposeTaskById(task.getId()));
} }
/** /**

View File

@ -67,7 +67,18 @@ public interface ValidGroups {
* *
* @author <huangxin@cmhi.chinamoblie.com> * @author <huangxin@cmhi.chinamoblie.com>
*/ */
interface TaskStartReqValid extends ProtocolCommonValid { interface TaskStartReqCommonValid extends ProtocolCommonValid {
}
interface TaskStartReqValid extends TaskStartReqCommonValid {
}
/**
* The interface Task start mul req valid.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
interface TaskStartMulReqValid extends TaskStartReqCommonValid {
} }
/** /**

View File

@ -0,0 +1,43 @@
package com.dispose.validation.valids;
import com.dispose.validation.valids.impl.ValidArrayIpAddrImpl;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The interface Valid array ip addr.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {ValidArrayIpAddrImpl.class})
public @interface ValidArrayIpAddr {
/**
* Message string.
*
* @return the string
*/
String message();
/**
* Groups class [ ].
*
* @return the class [ ]
*/
Class<?>[] groups() default {};
/**
* Payload class [ ].
*
* @return the class [ ]
*/
Class<? extends Payload>[] payload() default {};
}

View File

@ -0,0 +1,49 @@
package com.dispose.validation.valids.impl;
import com.dispose.common.ConstValue;
import com.dispose.validation.valids.ValidArrayIpAddr;
import inet.ipaddr.IPAddress;
import inet.ipaddr.IPAddressString;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
/**
* The type Valid array ip addr.
*
* @author <huangxin@cmhi.chinamoblie.com>
*/
public class ValidArrayIpAddrImpl implements ConstraintValidator<ValidArrayIpAddr, String[]> {
@Override
public boolean isValid(String[] strings, ConstraintValidatorContext constraintValidatorContext) {
if (strings == null || strings.length == 0) {
return false;
}
for (String s : strings) {
if (!Pattern.matches(ConstValue.IP_ADDR_REG, s)) {
return false;
}
IPAddressString addrString = new IPAddressString(s);
IPAddress addr = addrString.getAddress();
if (addr == null) {
return false;
}
if (!addr.isIPv4() && !addr.isIPv6()) {
return false;
}
}
return true;
}
@Override
public void initialize(ValidArrayIpAddr constraintAnnotation) {
}
}

View File

@ -34,6 +34,11 @@ public class ValidIpAddrImpl implements ConstraintValidator<ValidIpAddr, String>
*/ */
@Override @Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) { public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if(s == null || s.length() == 0) {
return false;
}
if (!Pattern.matches(ConstValue.IP_ADDR_REG, s)) { if (!Pattern.matches(ConstValue.IP_ADDR_REG, s)) {
return false; return false;
} }

View File

@ -1,6 +1,13 @@
package com.dispose.test.controller; package com.dispose.test.controller;
import com.dispose.common.*; import com.dispose.common.ConstValue;
import com.dispose.common.DDoSAttackType;
import com.dispose.common.DisposeCapacityType;
import com.dispose.common.DisposeConfigValue;
import com.dispose.common.DisposeTaskStatus;
import com.dispose.common.ErrorCode;
import com.dispose.common.NetflowDirection;
import com.dispose.common.ProtoCryptoType;
import com.dispose.mapper.DisposeDeviceMapper; import com.dispose.mapper.DisposeDeviceMapper;
import com.dispose.mapper.DisposeTaskMapper; import com.dispose.mapper.DisposeTaskMapper;
import com.dispose.pojo.dto.protocol.base.BaseIdResp; import com.dispose.pojo.dto.protocol.base.BaseIdResp;
@ -8,9 +15,10 @@ import com.dispose.pojo.dto.protocol.base.IdArraysReq;
import com.dispose.pojo.dto.protocol.base.ProtocolReqDTO; import com.dispose.pojo.dto.protocol.base.ProtocolReqDTO;
import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO; import com.dispose.pojo.dto.protocol.base.ProtocolRespDTO;
import com.dispose.pojo.dto.protocol.task.TaskStartReq; import com.dispose.pojo.dto.protocol.task.TaskStartReq;
import com.dispose.pojo.dto.protocol.task.TaskStopResp; import com.dispose.pojo.dto.protocol.task.TaskStopRsp;
import com.dispose.pojo.entity.DisposeTask; import com.dispose.pojo.entity.DisposeTask;
import com.dispose.test.Global.InitTestEnvironment; import com.dispose.test.Global.InitTestEnvironment;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jodd.net.HttpStatus; import jodd.net.HttpStatus;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -28,10 +36,8 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.core.type.TypeReference;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -234,14 +240,14 @@ public class DisposeTaskControllerTest extends InitTestEnvironment {
.getResponse() .getResponse()
.getContentAsString(); .getContentAsString();
ProtocolRespDTO<List<TaskStopResp>> rspInfo = objectMapper.readValue(ret, ProtocolRespDTO<List<TaskStopRsp>> rspInfo = objectMapper.readValue(ret,
new TypeReference<ProtocolRespDTO<List<TaskStopResp>>>() { new TypeReference<ProtocolRespDTO<List<TaskStopRsp>>>() {
}); });
verifyRespProtocol(rspInfo); verifyRespProtocol(rspInfo);
log.debug(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rspInfo)); log.debug(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rspInfo));
for (TaskStopResp t : rspInfo.getMsgContent() for (TaskStopRsp t : rspInfo.getMsgContent()
) { ) {
Assert.assertNotNull(t.getTaskId()); Assert.assertNotNull(t.getTaskId());
Assert.assertNotNull(t.getStatus()); Assert.assertNotNull(t.getStatus());

View File

@ -1,6 +1,10 @@
package com.dispose.test.service; package com.dispose.test.service;
import com.dispose.common.*; import com.dispose.common.DDoSAttackType;
import com.dispose.common.DisposeCapacityType;
import com.dispose.common.DisposeConfigValue;
import com.dispose.common.ErrorCode;
import com.dispose.common.NetflowDirection;
import com.dispose.manager.DisposeTaskManager; import com.dispose.manager.DisposeTaskManager;
import com.dispose.mapper.DisposeDeviceMapper; import com.dispose.mapper.DisposeDeviceMapper;
import com.dispose.mapper.UserAccountMapper; import com.dispose.mapper.UserAccountMapper;
@ -107,20 +111,20 @@ public class DisposeTaskServiceTest extends InitTestEnvironment {
log.info("creat new task: {}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(newTask)); log.info("creat new task: {}", objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(newTask));
MulReturnType<ErrorCode, Long> ret = disposeTaskService.createTask(newTask); MulReturnType<ErrorCode, DisposeTask> ret = disposeTaskService.createTask(newTask);
if (ret.getFirstParam() == ErrorCode.ERR_OK) { if (ret.getFirstParam() == ErrorCode.ERR_OK) {
Assert.assertNotNull(ret.getSecondParam()); Assert.assertNotNull(ret.getSecondParam());
} else { } else {
Assert.assertNotEquals(ret.getFirstParam().getCode(), ErrorCode.ERR_OK.getCode()); Assert.assertNotEquals(ret.getFirstParam().getCode(), ErrorCode.ERR_OK.getCode());
} }
Assert.assertEquals(ret.getSecondParam(), disposeTaskManager.getDisposeTask(newTask.getDeviceId(), Assert.assertEquals(ret.getSecondParam().getId(), disposeTaskManager.getDisposeTask(newTask.getDeviceId(),
newTask.getDisposeIp(), newTask.getDisposeCapacity()).getId()); newTask.getDisposeIp(), newTask.getDisposeCapacity()).getId());
ret = disposeTaskService.createTask(newTask); ret = disposeTaskService.createTask(newTask);
Assert.assertEquals(ret.getFirstParam().getCode(), ErrorCode.ERR_TASKRUNNING.getCode()); Assert.assertEquals(ret.getFirstParam().getCode(), ErrorCode.ERR_TASKRUNNING.getCode());
Assert.assertEquals(ret.getSecondParam(), disposeTaskManager.getDisposeTask(newTask.getDeviceId(), Assert.assertEquals(ret.getSecondParam().getId(), disposeTaskManager.getDisposeTask(newTask.getDeviceId(),
newTask.getDisposeIp(), newTask.getDisposeCapacity()).getId()); newTask.getDisposeIp(), newTask.getDisposeCapacity()).getId());
} }
} }