Browse Source

Merge remote-tracking branch 'origin/develop/3.6.4' into hotfix/3.6.3

pull/10394/head
ViacheslavKlimov 3 years ago
parent
commit
dc1a8dc35e
  1. 6
      application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java
  2. 22
      application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
  3. 47
      common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java

6
application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java

@ -33,13 +33,13 @@ public class ThingsboardErrorResponse {
// Error code // Error code
private final ThingsboardErrorCode errorCode; private final ThingsboardErrorCode errorCode;
private final Date timestamp; private final long timestamp;
protected ThingsboardErrorResponse(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) { protected ThingsboardErrorResponse(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) {
this.message = message; this.message = message;
this.errorCode = errorCode; this.errorCode = errorCode;
this.status = status; this.status = status;
this.timestamp = new java.util.Date(); this.timestamp = System.currentTimeMillis();
} }
public static ThingsboardErrorResponse of(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) { public static ThingsboardErrorResponse of(final String message, final ThingsboardErrorCode errorCode, HttpStatus status) {
@ -75,7 +75,7 @@ public class ThingsboardErrorResponse {
} }
@ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY) @ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY)
public Date getTimestamp() { public long getTimestamp() {
return timestamp; return timestamp;
} }
} }

22
application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java

@ -16,6 +16,8 @@
package org.thingsboard.server.exception; package org.thingsboard.server.exception;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpHeaders; 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;
@ -28,7 +30,9 @@ import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.WebRequest;
@ -43,16 +47,21 @@ import org.thingsboard.server.service.security.exception.JwtExpiredTokenExceptio
import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;
import org.thingsboard.server.service.security.exception.UserPasswordNotValidException; import org.thingsboard.server.service.security.exception.UserPasswordNotValidException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import static javax.servlet.RequestDispatcher.ERROR_EXCEPTION;
@Slf4j @Slf4j
@Controller
@RestControllerAdvice @RestControllerAdvice
public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler { public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHandler implements AccessDeniedHandler, ErrorController {
private static final Map<HttpStatus, ThingsboardErrorCode> statusToErrorCodeMap = new HashMap<>(); private static final Map<HttpStatus, ThingsboardErrorCode> statusToErrorCodeMap = new HashMap<>();
static { static {
@ -90,6 +99,17 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
return errorCodeToStatusMap.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR); return errorCodeToStatusMap.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR);
} }
@RequestMapping("/error")
public ResponseEntity<Object> handleError(HttpServletRequest request) {
HttpStatus httpStatus = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE))
.map(status -> HttpStatus.resolve(Integer.parseInt(status.toString())))
.orElse(HttpStatus.INTERNAL_SERVER_ERROR);
String errorMessage = Optional.ofNullable(request.getAttribute(ERROR_EXCEPTION))
.map(e -> (ExceptionUtils.getMessage((Throwable) e)))
.orElse(httpStatus.getReasonPhrase());
return new ResponseEntity<>(ThingsboardErrorResponse.of(errorMessage, statusToErrorCode(httpStatus), httpStatus), httpStatus);
}
@Override @Override
@ExceptionHandler(AccessDeniedException.class) @ExceptionHandler(AccessDeniedException.class)
public void handle(HttpServletRequest request, HttpServletResponse response, public void handle(HttpServletRequest request, HttpServletResponse response,

47
common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java

@ -157,12 +157,10 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
@Override @Override
public void fetch(TenantId tenantId) throws GitAPIException { public void fetch(TenantId tenantId) throws GitAPIException {
var repository = repositories.get(tenantId); var repository = checkRepository(tenantId);
if (repository != null) { log.debug("[{}] Fetching tenant repository.", tenantId);
log.debug("[{}] Fetching tenant repository.", tenantId); repository.fetch();
repository.fetch(); log.debug("[{}] Fetched tenant repository.", tenantId);
log.debug("[{}] Fetched tenant repository.", tenantId);
}
} }
@Override @Override
@ -195,8 +193,17 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
} }
private GitRepository checkRepository(TenantId tenantId) { private GitRepository checkRepository(TenantId tenantId) {
return Optional.ofNullable(repositories.get(tenantId)) GitRepository gitRepository = Optional.ofNullable(repositories.get(tenantId))
.orElseThrow(() -> new IllegalStateException("Repository is not initialized")); .orElseThrow(() -> new IllegalStateException("Repository is not initialized"));
if (!Files.exists(Path.of(gitRepository.getDirectory()))) {
try {
return cloneRepository(tenantId, gitRepository.getSettings());
} catch (Exception e) {
throw new IllegalStateException("Could not initialize the repository: " + e.getMessage(), e);
}
}
return gitRepository;
} }
@Override @Override
@ -229,17 +236,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
testRepository(tenantId, settings); testRepository(tenantId, settings);
clearRepository(tenantId); clearRepository(tenantId);
log.debug("[{}] Init tenant repository started.", tenantId); cloneRepository(tenantId, settings);
Path repositoryDirectory = Path.of(repositoriesFolder, tenantId.getId().toString());
GitRepository repository;
if (Files.exists(repositoryDirectory)) {
FileUtils.forceDelete(repositoryDirectory.toFile());
}
Files.createDirectories(repositoryDirectory);
repository = GitRepository.clone(settings, repositoryDirectory.toFile());
repositories.put(tenantId, repository);
log.debug("[{}] Init tenant repository completed.", tenantId);
} }
@Override @Override
@ -276,4 +273,18 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
String entityId = StringUtils.substringBetween(path, "/", ".json"); String entityId = StringUtils.substringBetween(path, "/", ".json");
return EntityIdFactory.getByTypeAndUuid(entityType, entityId); return EntityIdFactory.getByTypeAndUuid(entityType, entityId);
} }
private GitRepository cloneRepository(TenantId tenantId, RepositorySettings settings) throws Exception {
log.debug("[{}] Init tenant repository started.", tenantId);
Path repositoryDirectory = Path.of(repositoriesFolder, tenantId.getId().toString());
if (Files.exists(repositoryDirectory)) {
FileUtils.forceDelete(repositoryDirectory.toFile());
}
Files.createDirectories(repositoryDirectory);
GitRepository repository = GitRepository.clone(settings, repositoryDirectory.toFile());
repositories.put(tenantId, repository);
log.debug("[{}] Init tenant repository completed.", tenantId);
return repository;
}
} }

Loading…
Cancel
Save