Merge pull request #10436 from zzzeebra/transport_log_optimization
[3.7] Http Transport log optimization
This commit is contained in:
commit
ffad62892d
@ -16,12 +16,11 @@
|
|||||||
package org.thingsboard.server.transport.http;
|
package org.thingsboard.server.transport.http;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -31,6 +30,7 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -56,6 +56,7 @@ import org.thingsboard.server.gen.transport.TransportProtos;
|
|||||||
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg;
|
||||||
|
import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
|
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
|
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
|
||||||
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
|
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
|
||||||
@ -429,22 +430,17 @@ public class DeviceApiController implements TbTransportService {
|
|||||||
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
|
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
|
||||||
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
|
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
|
||||||
.setType(firmwareType.name()).build();
|
.setType(firmwareType.name()).build();
|
||||||
transportContext.getTransportService().process(sessionInfo, requestMsg, new GetOtaPackageCallback(responseWriter, title, version, size, chunk));
|
transportContext.getTransportService().process(sessionInfo, requestMsg, new GetOtaPackageCallback(transportContext, responseWriter, title, version, size, chunk));
|
||||||
}));
|
}));
|
||||||
return responseWriter;
|
return responseWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> {
|
@RequiredArgsConstructor
|
||||||
|
static class DeviceAuthCallback implements TransportServiceCallback<ValidateDeviceCredentialsResponse> {
|
||||||
private final TransportContext transportContext;
|
private final TransportContext transportContext;
|
||||||
private final DeferredResult<ResponseEntity> responseWriter;
|
private final DeferredResult<ResponseEntity> responseWriter;
|
||||||
private final Consumer<SessionInfoProto> onSuccess;
|
private final Consumer<SessionInfoProto> onSuccess;
|
||||||
|
|
||||||
DeviceAuthCallback(TransportContext transportContext, DeferredResult<ResponseEntity> responseWriter, Consumer<SessionInfoProto> onSuccess) {
|
|
||||||
this.transportContext = transportContext;
|
|
||||||
this.responseWriter = responseWriter;
|
|
||||||
this.onSuccess = onSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ValidateDeviceCredentialsResponse msg) {
|
public void onSuccess(ValidateDeviceCredentialsResponse msg) {
|
||||||
if (msg.hasDeviceInfo()) {
|
if (msg.hasDeviceInfo()) {
|
||||||
@ -456,18 +452,21 @@ public class DeviceApiController implements TbTransportService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable e) {
|
public void onError(Throwable e) {
|
||||||
log.warn("Failed to process request", e);
|
String body = null;
|
||||||
responseWriter.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
|
if (e instanceof HttpMessageNotReadableException || e instanceof JsonParseException) {
|
||||||
|
body = e.getMessage();
|
||||||
|
log.debug("Failed to process request in DeviceAuthCallback: {}", body);
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to process request in DeviceAuthCallback", e);
|
||||||
|
}
|
||||||
|
responseWriter.setResult(new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DeviceProvisionCallback implements TransportServiceCallback<ProvisionDeviceResponseMsg> {
|
@RequiredArgsConstructor
|
||||||
|
static class DeviceProvisionCallback implements TransportServiceCallback<ProvisionDeviceResponseMsg> {
|
||||||
private final DeferredResult<ResponseEntity> responseWriter;
|
private final DeferredResult<ResponseEntity> responseWriter;
|
||||||
|
|
||||||
DeviceProvisionCallback(DeferredResult<ResponseEntity> responseWriter) {
|
|
||||||
this.responseWriter = responseWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(ProvisionDeviceResponseMsg msg) {
|
public void onSuccess(ProvisionDeviceResponseMsg msg) {
|
||||||
responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg).toString(), HttpStatus.OK));
|
responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg).toString(), HttpStatus.OK));
|
||||||
@ -475,25 +474,25 @@ public class DeviceApiController implements TbTransportService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable e) {
|
public void onError(Throwable e) {
|
||||||
log.warn("Failed to process request", e);
|
String body = null;
|
||||||
responseWriter.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
|
if (e instanceof HttpMessageNotReadableException || e instanceof JsonParseException) {
|
||||||
|
body = e.getMessage();
|
||||||
|
log.debug("Failed to process request in DeviceProvisionCallback: {}", body);
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to process request in DeviceProvisionCallback", e);
|
||||||
|
}
|
||||||
|
responseWriter.setResult(new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class GetOtaPackageCallback implements TransportServiceCallback<TransportProtos.GetOtaPackageResponseMsg> {
|
@RequiredArgsConstructor
|
||||||
|
static class GetOtaPackageCallback implements TransportServiceCallback<GetOtaPackageResponseMsg> {
|
||||||
|
private final TransportContext transportContext;
|
||||||
private final DeferredResult<ResponseEntity> responseWriter;
|
private final DeferredResult<ResponseEntity> responseWriter;
|
||||||
private final String title;
|
private final String title;
|
||||||
private final String version;
|
private final String version;
|
||||||
private final int chuckSize;
|
private final int chunkSize;
|
||||||
private final int chuck;
|
private final int chunk;
|
||||||
|
|
||||||
GetOtaPackageCallback(DeferredResult<ResponseEntity> responseWriter, String title, String version, int chuckSize, int chuck) {
|
|
||||||
this.responseWriter = responseWriter;
|
|
||||||
this.title = title;
|
|
||||||
this.version = version;
|
|
||||||
this.chuckSize = chuckSize;
|
|
||||||
this.chuck = chuck;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(TransportProtos.GetOtaPackageResponseMsg otaPackageResponseMsg) {
|
public void onSuccess(TransportProtos.GetOtaPackageResponseMsg otaPackageResponseMsg) {
|
||||||
@ -501,7 +500,7 @@ public class DeviceApiController implements TbTransportService {
|
|||||||
responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_FOUND));
|
responseWriter.setResult(new ResponseEntity<>(HttpStatus.NOT_FOUND));
|
||||||
} else if (title.equals(otaPackageResponseMsg.getTitle()) && version.equals(otaPackageResponseMsg.getVersion())) {
|
} else if (title.equals(otaPackageResponseMsg.getTitle()) && version.equals(otaPackageResponseMsg.getVersion())) {
|
||||||
String otaPackageId = new UUID(otaPackageResponseMsg.getOtaPackageIdMSB(), otaPackageResponseMsg.getOtaPackageIdLSB()).toString();
|
String otaPackageId = new UUID(otaPackageResponseMsg.getOtaPackageIdMSB(), otaPackageResponseMsg.getOtaPackageIdLSB()).toString();
|
||||||
ByteArrayResource resource = new ByteArrayResource(transportContext.getOtaPackageDataCache().get(otaPackageId, chuckSize, chuck));
|
ByteArrayResource resource = new ByteArrayResource(transportContext.getOtaPackageDataCache().get(otaPackageId, chunkSize, chunk));
|
||||||
ResponseEntity<ByteArrayResource> response = ResponseEntity.ok()
|
ResponseEntity<ByteArrayResource> response = ResponseEntity.ok()
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackageResponseMsg.getFileName())
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + otaPackageResponseMsg.getFileName())
|
||||||
.header("x-filename", otaPackageResponseMsg.getFileName())
|
.header("x-filename", otaPackageResponseMsg.getFileName())
|
||||||
@ -516,8 +515,14 @@ public class DeviceApiController implements TbTransportService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable e) {
|
public void onError(Throwable e) {
|
||||||
log.warn("Failed to process request", e);
|
String body = null;
|
||||||
responseWriter.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
|
if (e instanceof HttpMessageNotReadableException || e instanceof JsonParseException) {
|
||||||
|
body = e.getMessage();
|
||||||
|
log.debug("Failed to process request in GetOtaPackageCallback: {}", body);
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to process request in GetOtaPackageCallback", e);
|
||||||
|
}
|
||||||
|
responseWriter.setResult(new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2024 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.transport.http;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
import org.thingsboard.server.common.transport.TransportContext;
|
||||||
|
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
class DeviceApiControllerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deviceAuthCallbackTest() {
|
||||||
|
TransportContext transportContext = Mockito.mock(TransportContext.class);
|
||||||
|
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class);
|
||||||
|
Consumer<TransportProtos.SessionInfoProto> onSuccess = x -> {
|
||||||
|
};
|
||||||
|
var callback = new DeviceApiController.DeviceAuthCallback(transportContext, responseWriter, onSuccess);
|
||||||
|
|
||||||
|
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax"));
|
||||||
|
|
||||||
|
callback.onError(new JsonParseException("Json ; expected"));
|
||||||
|
|
||||||
|
callback.onError(new IOException("not found"));
|
||||||
|
|
||||||
|
callback.onError(new RuntimeException("oops it is run time error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void deviceProvisionCallbackTest() {
|
||||||
|
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class);
|
||||||
|
var callback = new DeviceApiController.DeviceProvisionCallback(responseWriter);
|
||||||
|
|
||||||
|
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax"));
|
||||||
|
|
||||||
|
callback.onError(new JsonParseException("Json ; expected"));
|
||||||
|
|
||||||
|
callback.onError(new IOException("not found"));
|
||||||
|
|
||||||
|
callback.onError(new RuntimeException("oops it is run time error"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getOtaPackageCallback() {
|
||||||
|
TransportContext transportContext = Mockito.mock(TransportContext.class);
|
||||||
|
DeferredResult<ResponseEntity> responseWriter = Mockito.mock(DeferredResult.class);
|
||||||
|
String title = "Title";
|
||||||
|
String version = "version";
|
||||||
|
int chunkSize = 11;
|
||||||
|
int chunk = 3;
|
||||||
|
|
||||||
|
var callback = new DeviceApiController.GetOtaPackageCallback(transportContext, responseWriter, title, version, chunkSize, chunk);
|
||||||
|
|
||||||
|
callback.onError(new HttpMessageNotReadableException("JSON incorrect syntax"));
|
||||||
|
|
||||||
|
callback.onError(new JsonParseException("Json ; expected"));
|
||||||
|
|
||||||
|
callback.onError(new IOException("not found"));
|
||||||
|
|
||||||
|
callback.onError(new RuntimeException("oops it is run time error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
16
common/transport/http/src/test/resources/logback-test.xml
Normal file
16
common/transport/http/src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
logger name="org.thingsboard.server.transport.http.DeviceApiController" level="DEBUG" />
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="console"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
Loading…
x
Reference in New Issue
Block a user