diff --git a/pom.xml b/pom.xml index 92972d21..9c82e64e 100644 --- a/pom.xml +++ b/pom.xml @@ -301,9 +301,14 @@ org.springframework.boot spring-boot-starter-test - + test + + + org.springframework.boot + spring-boot-devtools + diff --git a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java index 041d7388..e72b8090 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/DynamicTask.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.conf; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.stereotype.Component; @@ -19,10 +18,8 @@ import java.util.concurrent.TimeUnit; * @author lin */ @Component +@Slf4j public class DynamicTask { - - private final Logger logger = LoggerFactory.getLogger(DynamicTask.class); - private ThreadPoolTaskScheduler threadPoolTaskScheduler; private final Map> futureMap = new ConcurrentHashMap<>(); @@ -48,9 +45,9 @@ public class DynamicTask { ScheduledFuture future = futureMap.get(key); if (future != null) { if (future.isCancelled()) { - logger.debug("任务【{}】已存在但是关闭状态!!!", key); + log.debug("任务【{}】已存在但是关闭状态!!!", key); } else { - logger.debug("任务【{}】已存在且已启动!!!", key); + log.debug("任务【{}】已存在且已启动!!!", key); return; } } @@ -59,9 +56,9 @@ public class DynamicTask { if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); - logger.debug("任务【{}】启动成功!!!", key); + log.debug("任务【{}】启动成功!!!", key); }else { - logger.debug("任务【{}】启动失败!!!", key); + log.debug("任务【{}】启动失败!!!", key); } } @@ -78,12 +75,12 @@ public class DynamicTask { // 获取执行的时刻 Instant startInstant = Instant.now().plusMillis(TimeUnit.MILLISECONDS.toMillis(delay)); - ScheduledFuture future = futureMap.get(key); + ScheduledFuture future = futureMap.get(key); if (future != null) { if (future.isCancelled()) { - logger.debug("任务【{}】已存在但是关闭状态!!!", key); + log.debug("任务【{}】已存在但是关闭状态!!!", key); } else { - logger.debug("任务【{}】已存在且已启动!!!", key); + log.debug("任务【{}】已存在且已启动!!!", key); return; } } @@ -92,9 +89,9 @@ public class DynamicTask { if (future != null){ futureMap.put(key, future); runnableMap.put(key, task); - logger.debug("任务【{}】启动成功!!!", key); + log.debug("任务【{}】启动成功!!!", key); }else { - logger.debug("任务【{}】启动失败!!!", key); + log.debug("任务【{}】启动失败!!!", key); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java index 05ecb078..d6dd3034 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java @@ -26,8 +26,8 @@ package com.genersoft.iot.vmp.gb28181.auth; import gov.nist.core.InternalErrorHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; import javax.sip.address.URI; import javax.sip.header.AuthorizationHeader; @@ -46,19 +46,14 @@ import java.util.Random; * @author M. Ranganathan * @author Marc Bednarek */ - +@Slf4j public class DigestServerAuthenticationHelper { - - private Logger logger = LoggerFactory.getLogger(DigestServerAuthenticationHelper.class); - - private MessageDigest messageDigest; + private final MessageDigest messageDigest; public static final String DEFAULT_ALGORITHM = "MD5"; public static final String DEFAULT_SCHEME = "Digest"; - - /** to hex converter */ private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; @@ -93,8 +88,8 @@ public class DigestServerAuthenticationHelper { long pad = rand.nextLong(); String nonceString = Long.valueOf(time).toString() + Long.valueOf(pad).toString(); - byte mdbytes[] = messageDigest.digest(nonceString.getBytes()); - return toHexString(mdbytes); + byte[] mdBytes = messageDigest.digest(nonceString.getBytes()); + return toHexString(mdBytes); } public Response generateChallenge(HeaderFactory headerFactory, Response response, String realm) { @@ -138,12 +133,9 @@ public class DigestServerAuthenticationHelper { return false; } - - - String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); + String A2 = request.getMethod().toUpperCase() + ":" + uri; String HA1 = hashedPassword; - byte[] mdbytes = messageDigest.digest(A2.getBytes()); String HA2 = toHexString(mdbytes); @@ -177,7 +169,7 @@ public class DigestServerAuthenticationHelper { String realm = authHeader.getRealm().trim(); String username = authHeader.getUsername().trim(); - if ( username == null || realm == null ) { + if(ObjectUtils.anyNull(username,realm)){ return false; } @@ -196,26 +188,22 @@ public class DigestServerAuthenticationHelper { // nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量 int nc = authHeader.getNonceCount(); String ncStr = String.format("%08x", nc).toUpperCase(); - // String ncStr = new DecimalFormat("00000000").format(nc); - // String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16)); + String A1 = String.join(":",username , realm , pass); + String A2 = String.join(":",request.getMethod().toUpperCase() , uri.toString()); - String A1 = username + ":" + realm + ":" + pass; - - String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); - - byte mdbytes[] = messageDigest.digest(A1.getBytes()); + byte[] mdbytes = messageDigest.digest(A1.getBytes()); String HA1 = toHexString(mdbytes); - logger.debug("A1: " + A1); - logger.debug("A2: " + A2); + log.debug("A1: " + A1); + log.debug("A2: " + A2); mdbytes = messageDigest.digest(A2.getBytes()); String HA2 = toHexString(mdbytes); - logger.debug("HA1: " + HA1); - logger.debug("HA2: " + HA2); + log.debug("HA1: " + HA1); + log.debug("HA2: " + HA2); // String cnonce = authHeader.getCNonce(); - logger.debug("nonce: " + nonce); - logger.debug("nc: " + ncStr); - logger.debug("cnonce: " + cnonce); - logger.debug("qop: " + qop); + log.debug("nonce: " + nonce); + log.debug("nc: " + ncStr); + log.debug("cnonce: " + cnonce); + log.debug("qop: " + qop); String KD = HA1 + ":" + nonce; if (qop != null && qop.equalsIgnoreCase("auth") ) { @@ -228,12 +216,12 @@ public class DigestServerAuthenticationHelper { KD += ":" + qop; } KD += ":" + HA2; - logger.debug("KD: " + KD); + log.debug("KD: " + KD); mdbytes = messageDigest.digest(KD.getBytes()); String mdString = toHexString(mdbytes); - logger.debug("mdString: " + mdString); + log.debug("mdString: " + mdString); String response = authHeader.getResponse(); - logger.debug("response: " + response); + log.debug("response: " + response); return mdString.equals(response); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index ceeb3b17..97d766f1 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -20,8 +20,8 @@ import gov.nist.javax.sip.address.SipUri; import gov.nist.javax.sip.header.SIPDateHeader; import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -43,32 +43,26 @@ import java.util.Locale; /** * SIP命令类型: REGISTER请求 */ +@Slf4j @Component +@RequiredArgsConstructor public class RegisterRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { + public static final String METHOD = "REGISTER"; + + private final SipConfig sipConfig; - private final Logger logger = LoggerFactory.getLogger(RegisterRequestProcessor.class); + private final SIPProcessorObserver sipProcessorObserver; - public final String method = "REGISTER"; + private final IDeviceService deviceService; - @Autowired - private SipConfig sipConfig; + private final SIPSender sipSender; - @Autowired - private SIPProcessorObserver sipProcessorObserver; - - @Autowired - private IDeviceService deviceService; - - @Autowired - private SIPSender sipSender; - - @Autowired - private UserSetting userSetting; + private final UserSetting userSetting; @Override public void afterPropertiesSet() throws Exception { // 添加消息处理的订阅 - sipProcessorObserver.addRequestProcessor(method, this); + sipProcessorObserver.addRequestProcessor(METHOD, this); } /** @@ -82,8 +76,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen RequestEventExt evtExt = (RequestEventExt) evt; SIPRequest request = (SIPRequest)evt.getRequest(); - Response response = null; - boolean passwordCorrect = false; + Response response; + boolean passwordCorrect; // 注册标志 boolean registerFlag; FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); @@ -96,11 +90,11 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); String requestAddress = remoteAddressInfo.getIp() + ":" + remoteAddressInfo.getPort(); - logger.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress); + log.info("[注册请求] 设备:{}, 开始处理: {}", deviceId, requestAddress); if (device != null && device.getSipTransactionInfo() != null && request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) { - logger.info("[注册请求] 设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId()); + log.info("[注册请求] 设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId()); device.setExpires(request.getExpires().getExpires()); device.setIp(remoteAddressInfo.getIp()); device.setPort(remoteAddressInfo.getPort()); @@ -120,7 +114,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword(); AuthorizationHeader authHead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME); if (authHead == null && !ObjectUtils.isEmpty(password)) { - logger.info("[注册请求] 设备:{}, 回复401: {}",deviceId, requestAddress); + log.info("[注册请求] 设备:{}, 回复401: {}",deviceId, requestAddress); response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request); new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getDomain()); sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); @@ -135,7 +129,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen // 注册失败 response = getMessageFactory().createResponse(Response.FORBIDDEN, request); response.setReasonPhrase("wrong password"); - logger.info("[注册请求] 设备:{}, 密码/SIP服务器ID错误, 回复403: {}", deviceId, requestAddress); + log.info("[注册请求] 设备:{}, 密码/SIP服务器ID错误, 回复403: {}", deviceId, requestAddress); sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); return; } @@ -199,16 +193,16 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen // 注册成功 // 保存到redis if (registerFlag) { - logger.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress); + log.info("[注册成功] deviceId: {}->{}", deviceId, requestAddress); device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); } else { - logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); + log.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); } } catch (SipException | NoSuchAlgorithmException | ParseException e) { - logger.error("未处理的异常 ", e); + log.error("未处理的异常 ", e); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java index 436d2a43..60ad7341 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java @@ -86,6 +86,7 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); logger.info("[回复ack] {}-> {}:{} ", sdp.getOrigin().getUsername(), event.getRemoteIpAddress(), event.getRemotePort()); + logger.debug("{}",reqAck); sipSender.transmitRequest( response.getLocalAddress().getHostAddress(), reqAck); } } catch (InvalidArgumentException | ParseException | SipException | SdpParseException e) { diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 870dee0b..b02d05c9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -424,10 +424,8 @@ public class PlatformController { @PostMapping("/catalog/add") @ResponseBody public void addCatalog(@RequestBody PlatformCatalog platformCatalog) { + logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog)); - if (logger.isDebugEnabled()) { - logger.debug("添加目录,{}", JSON.toJSONString(platformCatalog)); - } PlatformCatalog platformCatalogInStore = storager.getCatalog(platformCatalog.getPlatformId(), platformCatalog.getId()); if (platformCatalogInStore != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java index 286c8d57..a45d324b 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiControlController.java @@ -5,9 +5,8 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -22,15 +21,13 @@ import java.text.ParseException; @RestController @RequestMapping(value = "/api/v1/control") +@RequiredArgsConstructor +@Slf4j public class ApiControlController { - private final static Logger logger = LoggerFactory.getLogger(ApiControlController.class); + private final SIPCommander cmder; - @Autowired - private SIPCommander cmder; - - @Autowired - private IVideoManagerStorage storager; + private final IVideoManagerStorage storager; /** * 设备控制 - 云台控制 @@ -47,8 +44,8 @@ public class ApiControlController { @RequestParam(required = false)String code, @RequestParam(required = false)Integer speed){ - if (logger.isDebugEnabled()) { - logger.debug("模拟接口> 设备云台控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ", + if (log.isDebugEnabled()) { + log.debug("模拟接口> 设备云台控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ", serial, code, command, speed); } if (channel == null) {channel = 0;} @@ -99,7 +96,7 @@ public class ApiControlController { try { cmder.frontEndCmd(device, code, cmdCode, speed, speed, speed); } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 云台控制: {}", e.getMessage()); + log.error("[命令发送失败] 云台控制: {}", e.getMessage()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); } } @@ -121,8 +118,8 @@ public class ApiControlController { @RequestParam(required = false)String name, @RequestParam(required = false)Integer preset){ - if (logger.isDebugEnabled()) { - logger.debug("模拟接口> 预置位控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,name:{} ,preset:{} ", + if (log.isDebugEnabled()) { + log.debug("模拟接口> 预置位控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,name:{} ,preset:{} ", serial, code, command, name, preset); } @@ -148,7 +145,7 @@ public class ApiControlController { try { cmder.frontEndCmd(device, code, cmdCode, 0, preset, 0); } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 预置位控制: {}", e.getMessage()); + log.error("[命令发送失败] 预置位控制: {}", e.getMessage()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java index 7b59f7f7..e155d7c8 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; import com.github.pagehelper.PageInfo; +import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -28,27 +29,19 @@ import javax.sip.SipException; import java.text.ParseException; import java.util.*; -/** - * API兼容:设备信息 - */ -@SuppressWarnings("unchecked") @RestController @RequestMapping(value = "/api/v1/device") +@RequiredArgsConstructor public class ApiDeviceController { private final static Logger logger = LoggerFactory.getLogger(ApiDeviceController.class); + private final IVideoManagerStorage storager; + private final SIPCommander cmder; - @Autowired - private IVideoManagerStorage storager; + private final IDeviceService deviceService; - @Autowired - private SIPCommander cmder; - @Autowired - private IDeviceService deviceService; - - @Autowired - private DeferredResultHolder resultHolder; + private final DeferredResultHolder resultHolder; /** diff --git a/src/main/resources/logback-spring-local.xml b/src/main/resources/logback-spring-local.xml index dfda37e2..d876a362 100644 --- a/src/main/resources/logback-spring-local.xml +++ b/src/main/resources/logback-spring-local.xml @@ -90,7 +90,7 @@ - +