Merge with feature branch
This commit is contained in:
commit
49e91341de
@ -203,6 +203,20 @@ public class AdminController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Check version control settings exists (versionControlSettingsExists)",
|
||||
notes = "Check whether the version control settings exists. " + TENANT_AUTHORITY_PARAGRAPH)
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
@GetMapping("/vcSettings/exists")
|
||||
@ResponseBody
|
||||
public Boolean versionControlSettingsExists() throws ThingsboardException {
|
||||
try {
|
||||
accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
|
||||
return versionControlService.getVersionControlSettings(getTenantId()) != null;
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation(value = "Creates or Updates the version control settings (saveVersionControlSettings)",
|
||||
notes = "Creates or Updates the version control settings object. " + TENANT_AUTHORITY_PARAGRAPH)
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
|
||||
@ -15,17 +15,21 @@
|
||||
*/
|
||||
package org.thingsboard.server.controller;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
@ -33,25 +37,28 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.device.claim.ClaimResponse;
|
||||
import org.thingsboard.server.dao.device.claim.ClaimResult;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionLoadResult;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
|
||||
import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest;
|
||||
import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest;
|
||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE;
|
||||
import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION;
|
||||
import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION;
|
||||
|
||||
@RestController
|
||||
@TbCoreComponent
|
||||
@RequestMapping("/api/entities/vc")
|
||||
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
|
||||
@RequiredArgsConstructor
|
||||
@ -117,13 +124,18 @@ public class EntitiesVersionControlController extends BaseController {
|
||||
" \"name\": \"Device profile 1 version 1.0\"\n" +
|
||||
" }\n" +
|
||||
"]\n```")
|
||||
@GetMapping("/version/{branch}/{entityType}/{externalEntityUuid}")
|
||||
public DeferredResult<List<EntityVersion>> listEntityVersions(@PathVariable String branch,
|
||||
@GetMapping(value = "/version/{branch}/{entityType}/{externalEntityUuid}", params = {"pageSize", "page"})
|
||||
public DeferredResult<PageData<EntityVersion>> listEntityVersions(@PathVariable String branch,
|
||||
@PathVariable EntityType entityType,
|
||||
@PathVariable UUID externalEntityUuid) throws ThingsboardException {
|
||||
@PathVariable UUID externalEntityUuid,
|
||||
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
|
||||
@RequestParam int pageSize,
|
||||
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
|
||||
@RequestParam int page) throws ThingsboardException {
|
||||
try {
|
||||
EntityId externalEntityId = EntityIdFactory.getByTypeAndUuid(entityType, externalEntityUuid);
|
||||
return wrapFuture(versionControlService.listEntityVersions(getTenantId(), branch, externalEntityId));
|
||||
PageLink pageLink = new PageLink(pageSize, page);
|
||||
return wrapFuture(versionControlService.listEntityVersions(getTenantId(), branch, externalEntityId, pageLink));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -136,11 +148,16 @@ public class EntitiesVersionControlController extends BaseController {
|
||||
" \"name\": \"Device profiles from dev\"\n" +
|
||||
" }\n" +
|
||||
"]\n```")
|
||||
@GetMapping("/version/{branch}/{entityType}")
|
||||
public DeferredResult<List<EntityVersion>> listEntityTypeVersions(@PathVariable String branch,
|
||||
@PathVariable EntityType entityType) throws ThingsboardException {
|
||||
@GetMapping(value = "/version/{branch}/{entityType}", params = {"pageSize", "page"})
|
||||
public DeferredResult<PageData<EntityVersion>> listEntityTypeVersions(@PathVariable String branch,
|
||||
@PathVariable EntityType entityType,
|
||||
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
|
||||
@RequestParam int pageSize,
|
||||
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
|
||||
@RequestParam int page) throws ThingsboardException {
|
||||
try {
|
||||
return wrapFuture(versionControlService.listEntityTypeVersions(getTenantId(), branch, entityType));
|
||||
PageLink pageLink = new PageLink(pageSize, page);
|
||||
return wrapFuture(versionControlService.listEntityTypeVersions(getTenantId(), branch, entityType, pageLink));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
@ -161,10 +178,15 @@ public class EntitiesVersionControlController extends BaseController {
|
||||
" \"name\": \"Devices added\"\n" +
|
||||
" }\n" +
|
||||
"]\n```")
|
||||
@GetMapping("/version/{branch}")
|
||||
public DeferredResult<List<EntityVersion>> listVersions(@PathVariable String branch) throws ThingsboardException {
|
||||
@GetMapping(value = "/version/{branch}", params = {"pageSize", "page"})
|
||||
public DeferredResult<PageData<EntityVersion>> listVersions(@PathVariable String branch,
|
||||
@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true)
|
||||
@RequestParam int pageSize,
|
||||
@ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true)
|
||||
@RequestParam int page) throws ThingsboardException {
|
||||
try {
|
||||
return wrapFuture(versionControlService.listVersions(getTenantId(), branch));
|
||||
PageLink pageLink = new PageLink(pageSize, page);
|
||||
return wrapFuture(versionControlService.listVersions(getTenantId(), branch, pageLink));
|
||||
} catch (Exception e) {
|
||||
throw handleException(e);
|
||||
}
|
||||
|
||||
@ -37,6 +37,9 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportSettings;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityImportResult;
|
||||
@ -160,18 +163,18 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listEntityVersions(TenantId tenantId, String branch, EntityId externalId) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch, externalId);
|
||||
public ListenableFuture<PageData<EntityVersion>> listEntityVersions(TenantId tenantId, String branch, EntityId externalId, PageLink pageLink) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch, externalId, pageLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listEntityTypeVersions(TenantId tenantId, String branch, EntityType entityType) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch, entityType);
|
||||
public ListenableFuture<PageData<EntityVersion>> listEntityTypeVersions(TenantId tenantId, String branch, EntityType entityType, PageLink pageLink) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch, entityType, pageLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch);
|
||||
public ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, PageLink pageLink) throws Exception {
|
||||
return gitServiceQueue.listVersions(tenantId, branch, pageLink);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -336,6 +339,12 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
adminSettings.setKey(SETTINGS_KEY);
|
||||
adminSettings.setTenantId(tenantId);
|
||||
}
|
||||
try {
|
||||
//TODO: ashvayka: replace future.get with deferred result. Don't forget to call when tenant is deleted.
|
||||
gitServiceQueue.initRepository(tenantId, versionControlSettings).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to init repository!", e);
|
||||
}
|
||||
adminSettings.setJsonValue(JacksonUtil.valueToTree(versionControlSettings));
|
||||
AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings);
|
||||
EntitiesVersionControlSettings savedVersionControlSettings;
|
||||
@ -344,12 +353,6 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load version control settings!", e);
|
||||
}
|
||||
try {
|
||||
//TODO: ashvayka: replace future.get with deferred result. Don't forget to call when tenant is deleted.
|
||||
gitServiceQueue.initRepository(tenantId, versionControlSettings).get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to init repository!", e);
|
||||
}
|
||||
return savedVersionControlSettings;
|
||||
}
|
||||
|
||||
|
||||
@ -16,15 +16,14 @@
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import com.google.protobuf.ByteString;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.cluster.TbClusterService;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
@ -32,6 +31,8 @@ import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
@ -73,7 +74,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
private final DefaultEntitiesVersionControlService entitiesVersionControlService;
|
||||
|
||||
private final Map<UUID, PendingGitRequest<?>> pendingRequestMap = new HashMap<>();
|
||||
private final ObjectWriter jsonWriter = new ObjectMapper().writer(SerializationFeature.INDENT_OUTPUT);
|
||||
private final ObjectMapper jsonMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
|
||||
|
||||
public DefaultGitVersionControlQueueService(TbServiceInfoProvider serviceInfoProvider, TbClusterService clusterService,
|
||||
DataDecodingEncodingService encodingService,
|
||||
@ -102,7 +103,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
String path = getRelativePath(entityData.getEntityType(), entityData.getEntity().getId());
|
||||
String entityDataJson;
|
||||
try {
|
||||
entityDataJson = jsonWriter.writeValueAsString(entityData);
|
||||
entityDataJson = jsonMapper.writeValueAsString(entityData);
|
||||
} catch (IOException e) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
throw new RuntimeException(e);
|
||||
@ -144,29 +145,36 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch) {
|
||||
public ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, PageLink pageLink) {
|
||||
return listVersions(tenantId, ListVersionsRequestMsg.newBuilder()
|
||||
.setBranchName(branch).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityType entityType) {
|
||||
return listVersions(tenantId, ListVersionsRequestMsg.newBuilder()
|
||||
.setBranchName(branch).setEntityType(entityType.name())
|
||||
.setBranchName(branch)
|
||||
.setPageSize(pageLink.getPageSize())
|
||||
.setPage(pageLink.getPage())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityId entityId) {
|
||||
public ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityType entityType, PageLink pageLink) {
|
||||
return listVersions(tenantId, ListVersionsRequestMsg.newBuilder()
|
||||
.setBranchName(branch).setEntityType(entityType.name())
|
||||
.setPageSize(pageLink.getPageSize())
|
||||
.setPage(pageLink.getPage())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityId entityId, PageLink pageLink) {
|
||||
return listVersions(tenantId, ListVersionsRequestMsg.newBuilder()
|
||||
.setBranchName(branch)
|
||||
.setEntityType(entityId.getEntityType().name())
|
||||
.setEntityIdMSB(entityId.getId().getMostSignificantBits())
|
||||
.setEntityIdLSB(entityId.getId().getLeastSignificantBits())
|
||||
.setPageSize(pageLink.getPageSize())
|
||||
.setPage(pageLink.getPage())
|
||||
.build());
|
||||
}
|
||||
|
||||
private ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, ListVersionsRequestMsg requestMsg) {
|
||||
private ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, ListVersionsRequestMsg requestMsg) {
|
||||
ListVersionsGitRequest request = new ListVersionsGitRequest(tenantId);
|
||||
|
||||
registerAndSend(request, builder -> builder.setListVersionRequest(requestMsg).build(), wrap(request.getFuture()));
|
||||
@ -318,8 +326,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
listEntitiesResponse.getEntitiesList().stream().map(this::getVersionedEntityInfo).collect(Collectors.toList()));
|
||||
} else if (vcResponseMsg.hasListVersionsResponse()) {
|
||||
var listVersionsResponse = vcResponseMsg.getListVersionsResponse();
|
||||
((ListVersionsGitRequest) request).getFuture().set(
|
||||
listVersionsResponse.getVersionsList().stream().map(this::getEntityVersion).collect(Collectors.toList()));
|
||||
((ListVersionsGitRequest) request).getFuture().set(toPageData(listVersionsResponse));
|
||||
} else if (vcResponseMsg.hasEntityContentResponse()) {
|
||||
var data = vcResponseMsg.getEntityContentResponse().getData();
|
||||
((EntityContentGitRequest) request).getFuture().set(toData(data));
|
||||
@ -331,6 +338,11 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
}
|
||||
}
|
||||
|
||||
private PageData<EntityVersion> toPageData(TransportProtos.ListVersionsResponseMsg listVersionsResponse) {
|
||||
var listVersions = listVersionsResponse.getVersionsList().stream().map(this::getEntityVersion).collect(Collectors.toList());
|
||||
return new PageData<>(listVersions, listVersionsResponse.getTotalPages(), listVersionsResponse.getTotalElements(), listVersionsResponse.getHasNext());
|
||||
}
|
||||
|
||||
private EntityVersion getEntityVersion(TransportProtos.EntityVersionProto proto) {
|
||||
return new EntityVersion(proto.getId(), proto.getName());
|
||||
}
|
||||
@ -340,8 +352,9 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@SneakyThrows
|
||||
private EntityExportData toData(String data) {
|
||||
return JacksonUtil.fromString(data, EntityExportData.class);
|
||||
return jsonMapper.readValue(data, EntityExportData.class);
|
||||
}
|
||||
|
||||
private static <T> TbQueueCallback wrap(SettableFuture<T> future) {
|
||||
|
||||
@ -20,6 +20,8 @@ import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.service.security.model.SecurityUser;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
@ -38,11 +40,11 @@ public interface EntitiesVersionControlService {
|
||||
|
||||
ListenableFuture<VersionCreationResult> saveEntitiesVersion(SecurityUser user, VersionCreateRequest request) throws Exception;
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listEntityVersions(TenantId tenantId, String branch, EntityId externalId) throws Exception;
|
||||
ListenableFuture<PageData<EntityVersion>> listEntityVersions(TenantId tenantId, String branch, EntityId externalId, PageLink pageLink) throws Exception;
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listEntityTypeVersions(TenantId tenantId, String branch, EntityType entityType) throws Exception;
|
||||
ListenableFuture<PageData<EntityVersion>> listEntityTypeVersions(TenantId tenantId, String branch, EntityType entityType, PageLink pageLink) throws Exception;
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch) throws Exception;
|
||||
ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, PageLink pageLink) throws Exception;
|
||||
|
||||
ListenableFuture<List<VersionedEntityInfo>> listEntitiesAtVersion(TenantId tenantId, String branch, String versionId, EntityType entityType) throws Exception;
|
||||
|
||||
|
||||
@ -20,6 +20,8 @@ import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
@ -40,11 +42,11 @@ public interface GitVersionControlQueueService {
|
||||
|
||||
ListenableFuture<VersionCreationResult> push(CommitGitRequest commit);
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch);
|
||||
ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, PageLink pageLink);
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityType entityType);
|
||||
ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityType entityType, PageLink pageLink);
|
||||
|
||||
ListenableFuture<List<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityId entityId);
|
||||
ListenableFuture<PageData<EntityVersion>> listVersions(TenantId tenantId, String branch, EntityId entityId, PageLink pageLink);
|
||||
|
||||
ListenableFuture<List<VersionedEntityInfo>> listEntitiesAtVersion(TenantId tenantId, String branch, String versionId, EntityType entityType);
|
||||
|
||||
|
||||
@ -16,13 +16,14 @@
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ListVersionsGitRequest extends PendingGitRequest<List<EntityVersion>> {
|
||||
public class ListVersionsGitRequest extends PendingGitRequest<PageData<EntityVersion>> {
|
||||
|
||||
public ListVersionsGitRequest(TenantId tenantId) {
|
||||
super(tenantId);
|
||||
|
||||
@ -1122,8 +1122,8 @@ metrics:
|
||||
vc:
|
||||
thread_pool_size: "${TB_VC_POOL_SIZE:4}"
|
||||
git:
|
||||
folder: "${TB_VC_GIT_FOLDER:}"
|
||||
repos-poll-interval: "${TB_VC_GIT_REPOS_POLL_INTERVAL_SEC:60}"
|
||||
repositories-folder: "${TB_VC_GIT_REPOSITORIES_FOLDER:${java.io.tmpdir}/repositories}"
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
|
||||
@ -721,6 +721,8 @@ message ListVersionsRequestMsg {
|
||||
string entityType = 2;
|
||||
int64 entityIdMSB = 3;
|
||||
int64 entityIdLSB = 4;
|
||||
int32 pageSize = 5;
|
||||
int32 page = 6;
|
||||
}
|
||||
|
||||
message EntityVersionProto {
|
||||
@ -731,6 +733,9 @@ message EntityVersionProto {
|
||||
|
||||
message ListVersionsResponseMsg {
|
||||
repeated EntityVersionProto versions = 1;
|
||||
int32 totalPages = 2;
|
||||
int64 totalElements = 3;
|
||||
bool hasNext = 4;
|
||||
}
|
||||
|
||||
message ListEntitiesRequestMsg {
|
||||
|
||||
@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
@ -30,7 +31,7 @@ import org.thingsboard.server.common.data.sync.JsonTbEntity;
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "entityType", defaultImpl = EntityExportData.class)
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "entityType", include = As.EXISTING_PROPERTY, visible = true, defaultImpl = EntityExportData.class)
|
||||
@JsonSubTypes({
|
||||
@Type(name = "DEVICE", value = DeviceExportData.class),
|
||||
@Type(name = "RULE_CHAIN", value = RuleChainExportData.class)
|
||||
|
||||
@ -15,26 +15,20 @@
|
||||
*/
|
||||
package org.thingsboard.server.common.data.sync.ie;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.sync.JsonTbEntity;
|
||||
import org.thingsboard.server.common.data.sync.ThrowingRunnable;
|
||||
|
||||
@Data
|
||||
public class EntityImportResult<E extends ExportableEntity<? extends EntityId>> {
|
||||
|
||||
@JsonTbEntity
|
||||
private E savedEntity;
|
||||
@JsonTbEntity
|
||||
private E oldEntity;
|
||||
private EntityType entityType;
|
||||
|
||||
@JsonIgnore
|
||||
private ThrowingRunnable saveReferencesCallback = () -> {};
|
||||
@JsonIgnore
|
||||
private ThrowingRunnable sendEventsCallback = () -> {};
|
||||
|
||||
public void addSaveReferencesCallback(ThrowingRunnable callback) {
|
||||
|
||||
@ -68,7 +68,6 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
|
||||
|
||||
public interface ClusterVersionControlService extends ApplicationListener<PartitionChangeEvent> {
|
||||
}
|
||||
|
||||
@ -26,15 +26,33 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
|
||||
import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.*;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.AddMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.CommitRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.CommitResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.DeleteMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.EntitiesContentRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.EntitiesContentResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.EntityContentRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.EntityContentResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.EntityVersionProto;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListBranchesRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListBranchesResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListEntitiesRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListEntitiesResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListVersionsRequestMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ListVersionsResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.PrepareMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.ToVersionControlServiceMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.VersionControlResponseMsg;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.VersionedEntityInfoProto;
|
||||
import org.thingsboard.server.queue.TbQueueConsumer;
|
||||
import org.thingsboard.server.queue.TbQueueProducer;
|
||||
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
|
||||
@ -220,12 +238,16 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
} else {
|
||||
path = null;
|
||||
}
|
||||
var data = vcService.listVersions(ctx.getTenantId(), request.getBranchName(), path);
|
||||
var data = vcService.listVersions(ctx.getTenantId(), request.getBranchName(), path, new PageLink(request.getPageSize(), request.getPage()));
|
||||
reply(ctx, Optional.empty(), builder ->
|
||||
builder.setListVersionsResponse(ListVersionsResponseMsg.newBuilder()
|
||||
.addAllVersions(data.stream().map(
|
||||
.setTotalPages(data.getTotalPages())
|
||||
.setTotalElements(data.getTotalElements())
|
||||
.setHasNext(data.hasNext())
|
||||
.addAllVersions(data.getData().stream().map(
|
||||
v -> EntityVersionProto.newBuilder().setId(v.getId()).setName(v.getName()).build()
|
||||
).collect(Collectors.toList()))));
|
||||
).collect(Collectors.toList())))
|
||||
);
|
||||
}
|
||||
|
||||
private void handleListEntities(VersionControlRequestCtx ctx, ListEntitiesRequestMsg request) throws Exception {
|
||||
@ -266,7 +288,9 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
} else if (request.hasDeleteMsg()) {
|
||||
deleteFromCommit(ctx, current, request.getDeleteMsg());
|
||||
} else if (request.hasPushMsg()) {
|
||||
reply(ctx, vcService.push(current));
|
||||
var result = vcService.push(current);
|
||||
pendingCommitMap.remove(ctx.getTenantId());
|
||||
reply(ctx, result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
doAbortCurrentCommit(tenantId, current, e);
|
||||
|
||||
@ -15,12 +15,11 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -28,6 +27,8 @@ import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
@ -57,7 +58,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
@Value("${java.io.tmpdir}/repositories")
|
||||
private String defaultFolder;
|
||||
|
||||
@Value("${vc.git.folder:${java.io.tmpdir}/repositories}")
|
||||
@Value("${vc.git.repositories-folder:${java.io.tmpdir}/repositories}")
|
||||
private String repositoriesFolder;
|
||||
|
||||
@Value("${vc.git.repos-poll-interval:60}")
|
||||
@ -97,22 +98,12 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
String branch = commit.getBranch();
|
||||
try {
|
||||
repository.fetch();
|
||||
if (repository.listBranches().contains(branch)) {
|
||||
repository.checkout("origin/" + branch, false);
|
||||
try {
|
||||
repository.checkout(branch, true);
|
||||
} catch (RefAlreadyExistsException e) {
|
||||
repository.checkout(branch, false);
|
||||
}
|
||||
|
||||
repository.createAndCheckoutOrphanBranch(commit.getWorkingBranch());
|
||||
repository.resetAndClean();
|
||||
|
||||
if (repository.listRemoteBranches().contains(branch)) {
|
||||
repository.merge(branch);
|
||||
} else { // TODO [viacheslav]: rollback orphan branch on failure
|
||||
try {
|
||||
repository.createAndCheckoutOrphanBranch(branch); // FIXME [viacheslav]: Checkout returned unexpected result NO_CHANGE for master branch
|
||||
} catch (JGitInternalException e) {
|
||||
if (!e.getMessage().contains("NO_CHANGE")) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | GitAPIException gitAPIException) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
@ -145,24 +136,44 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
result.setRemoved(status.getRemoved().size());
|
||||
|
||||
GitRepository.Commit gitCommit = repository.commit(commit.getVersionName());
|
||||
repository.push();
|
||||
repository.push(commit.getWorkingBranch(), commit.getBranch());
|
||||
|
||||
result.setVersion(toVersion(gitCommit));
|
||||
return result;
|
||||
} catch (GitAPIException gitAPIException) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
throw new RuntimeException(gitAPIException);
|
||||
} finally {
|
||||
cleanUp(commit);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void cleanUp(PendingCommit commit) {
|
||||
GitRepository repository = checkRepository(commit.getTenantId());
|
||||
try {
|
||||
repository.createAndCheckoutOrphanBranch(EntityId.NULL_UUID.toString());
|
||||
} catch (Exception e) {
|
||||
if (!e.getMessage().contains("NO_CHANGE")) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
repository.resetAndClean();
|
||||
repository.deleteLocalBranchIfExists(commit.getWorkingBranch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(PendingCommit commit) {
|
||||
//TODO: implement;
|
||||
cleanUp(commit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetch(TenantId tenantId) {
|
||||
//Fetch latest changes on demand.
|
||||
public void fetch(TenantId tenantId) throws GitAPIException {
|
||||
var repository = repositories.get(tenantId);
|
||||
if (repository != null) {
|
||||
repository.fetch();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -175,7 +186,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
public List<String> listBranches(TenantId tenantId) {
|
||||
GitRepository repository = checkRepository(tenantId);
|
||||
try {
|
||||
return repository.listBranches();
|
||||
return repository.listRemoteBranches();
|
||||
} catch (GitAPIException gitAPIException) {
|
||||
//TODO: analyze and return meaningful exceptions that we can show to the client;
|
||||
throw new RuntimeException(gitAPIException);
|
||||
@ -183,7 +194,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
}
|
||||
|
||||
private EntityVersion checkVersion(TenantId tenantId, String branch, String versionId) throws Exception {
|
||||
return listVersions(tenantId, branch, null).stream()
|
||||
return listVersions(tenantId, branch, null, new PageLink(Integer.MAX_VALUE)).getData().stream()
|
||||
.filter(version -> version.getId().equals(versionId))
|
||||
.findFirst().orElseThrow(() -> new IllegalArgumentException("Version not found"));
|
||||
}
|
||||
@ -194,11 +205,9 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntityVersion> listVersions(TenantId tenantId, String branch, String path) throws Exception {
|
||||
public PageData<EntityVersion> listVersions(TenantId tenantId, String branch, String path, PageLink pageLink) throws Exception {
|
||||
GitRepository repository = checkRepository(tenantId);
|
||||
return repository.listCommits(branch, path, Integer.MAX_VALUE).stream()
|
||||
.map(this::toVersion)
|
||||
.collect(Collectors.toList());
|
||||
return repository.listCommits(branch, path, pageLink).mapData(this::toVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -15,11 +15,20 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.sshd.common.util.security.SecurityUtils;
|
||||
import org.eclipse.jgit.api.*;
|
||||
import org.eclipse.jgit.api.CloneCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.GitCommand;
|
||||
import org.eclipse.jgit.api.ListBranchCommand;
|
||||
import org.eclipse.jgit.api.LogCommand;
|
||||
import org.eclipse.jgit.api.LsRemoteCommand;
|
||||
import org.eclipse.jgit.api.ResetCommand;
|
||||
import org.eclipse.jgit.api.TransportCommand;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
@ -28,6 +37,7 @@ import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.filter.RevFilter;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.transport.SshTransport;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.eclipse.jgit.transport.sshd.JGitKeyCache;
|
||||
@ -36,7 +46,8 @@ import org.eclipse.jgit.transport.sshd.SshdSessionFactory;
|
||||
import org.eclipse.jgit.transport.sshd.SshdSessionFactoryBuilder;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionControlAuthMethod;
|
||||
|
||||
@ -51,6 +62,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GitRepository {
|
||||
@ -119,15 +131,18 @@ public class GitRepository {
|
||||
.setRemoveDeletedRefs(true));
|
||||
}
|
||||
|
||||
public void checkout(String branch, boolean createBranch) throws GitAPIException {
|
||||
execute(git.checkout()
|
||||
.setCreateBranch(createBranch)
|
||||
.setName(branch));
|
||||
public void deleteLocalBranchIfExists(String branch) throws GitAPIException {
|
||||
execute(git.branchDelete()
|
||||
.setBranchNames(branch)
|
||||
.setForce(true));
|
||||
}
|
||||
|
||||
public void reset() throws GitAPIException {
|
||||
public void resetAndClean() throws GitAPIException {
|
||||
execute(git.reset()
|
||||
.setMode(ResetCommand.ResetType.HARD));
|
||||
execute(git.clean()
|
||||
.setForce(true)
|
||||
.setCleanDirectories(true));
|
||||
}
|
||||
|
||||
public void merge(String branch) throws IOException, GitAPIException {
|
||||
@ -140,36 +155,34 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
|
||||
public List<String> listBranches() throws GitAPIException {
|
||||
public List<String> listRemoteBranches() throws GitAPIException {
|
||||
return execute(git.branchList()
|
||||
.setListMode(ListBranchCommand.ListMode.ALL)).stream()
|
||||
.setListMode(ListBranchCommand.ListMode.REMOTE)).stream()
|
||||
.filter(ref -> !ref.getName().equals(Constants.HEAD))
|
||||
.map(ref -> org.eclipse.jgit.lib.Repository.shortenRefName(ref.getName()))
|
||||
.map(name -> StringUtils.removeStart(name, "origin/"))
|
||||
.distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Commit> listCommits(String branch, int limit) throws IOException, GitAPIException {
|
||||
return listCommits(branch, null, limit);
|
||||
public PageData<Commit> listCommits(String branch, PageLink pageLink) throws IOException, GitAPIException {
|
||||
return listCommits(branch, null, pageLink);
|
||||
}
|
||||
|
||||
public List<Commit> listCommits(String branch, String path, int limit) throws IOException, GitAPIException {
|
||||
public PageData<Commit> listCommits(String branch, String path, PageLink pageLink) throws IOException, GitAPIException {
|
||||
ObjectId branchId = resolve("origin/" + branch);
|
||||
if (branchId == null) {
|
||||
throw new IllegalArgumentException("Branch not found");
|
||||
}
|
||||
LogCommand command = git.log()
|
||||
.add(branchId).setMaxCount(limit)
|
||||
.add(branchId)
|
||||
.setRevFilter(RevFilter.NO_MERGES);
|
||||
if (StringUtils.isNotEmpty(path)) {
|
||||
command.addPath(path);
|
||||
}
|
||||
return Streams.stream(execute(command))
|
||||
.map(this::toCommit)
|
||||
.collect(Collectors.toList());
|
||||
Iterable<RevCommit> commits = execute(command);
|
||||
return iterableToPageData(commits, this::toCommit, pageLink);
|
||||
}
|
||||
|
||||
|
||||
public List<String> listFilesAtCommit(String commitId) throws IOException {
|
||||
return listFilesAtCommit(commitId, null);
|
||||
}
|
||||
@ -212,16 +225,9 @@ public class GitRepository {
|
||||
.setOrphan(true)
|
||||
.setForced(true)
|
||||
.setName(name));
|
||||
// Set<String> uncommittedChanges = git.status().call().getUncommittedChanges();
|
||||
// if (!uncommittedChanges.isEmpty()) {
|
||||
// RmCommand rm = git.rm();
|
||||
// uncommittedChanges.forEach(rm::addFilepattern);
|
||||
// execute(rm);
|
||||
// }
|
||||
// execute(git.clean());
|
||||
}
|
||||
|
||||
public void add(String filesPattern) throws GitAPIException { // FIXME [viacheslav]
|
||||
public void add(String filesPattern) throws GitAPIException {
|
||||
execute(git.add().setUpdate(true).addFilepattern(filesPattern));
|
||||
execute(git.add().addFilepattern(filesPattern));
|
||||
}
|
||||
@ -233,13 +239,14 @@ public class GitRepository {
|
||||
|
||||
public Commit commit(String message) throws GitAPIException {
|
||||
RevCommit revCommit = execute(git.commit()
|
||||
.setMessage(message)); // TODO [viacheslav]: set configurable author for commit
|
||||
.setMessage(message));
|
||||
return toCommit(revCommit);
|
||||
}
|
||||
|
||||
|
||||
public void push() throws GitAPIException {
|
||||
execute(git.push());
|
||||
public void push(String localBranch, String remoteBranch) throws GitAPIException {
|
||||
execute(git.push()
|
||||
.setRefSpecs(new RefSpec(localBranch + ":" + remoteBranch)));
|
||||
}
|
||||
|
||||
|
||||
@ -293,6 +300,23 @@ public class GitRepository {
|
||||
return command.call();
|
||||
}
|
||||
|
||||
private static <T,R> PageData<R> iterableToPageData (Iterable<T> iterable, Function<? super T, ? extends R> mapper, PageLink pageLink) {
|
||||
int totalElements = Iterables.size(iterable);
|
||||
int totalPages = pageLink.getPageSize() > 0 ? (int) Math.ceil((float) totalElements / pageLink.getPageSize()) : 1;
|
||||
int startIndex = pageLink.getPageSize() * pageLink.getPage();
|
||||
int limit = startIndex + pageLink.getPageSize();
|
||||
iterable = Iterables.limit(iterable, limit);
|
||||
if (startIndex < totalElements) {
|
||||
iterable = Iterables.skip(iterable, startIndex);
|
||||
} else {
|
||||
iterable = Collections.emptyList();
|
||||
}
|
||||
List<R> data = Streams.stream(iterable).map(mapper)
|
||||
.collect(Collectors.toList());
|
||||
boolean hasNext = pageLink.getPageSize() > 0 && totalElements > startIndex + data.size();
|
||||
return new PageData<>(data, totalPages, totalElements, hasNext);
|
||||
}
|
||||
|
||||
private static void configureTransportCommand(TransportCommand transportCommand, CredentialsProvider credentialsProvider, SshdSessionFactory sshSessionFactory) {
|
||||
if (credentialsProvider != null) {
|
||||
transportCommand.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntitiesVersionControlSettings;
|
||||
import org.thingsboard.server.common.data.sync.vc.EntityVersion;
|
||||
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
|
||||
@ -28,7 +31,7 @@ public interface GitRepositoryService {
|
||||
|
||||
void prepareCommit(PendingCommit pendingCommit);
|
||||
|
||||
List<EntityVersion> listVersions(TenantId tenantId, String branch, String path) throws Exception;
|
||||
PageData<EntityVersion> listVersions(TenantId tenantId, String branch, String path, PageLink pageLink) throws Exception;
|
||||
|
||||
List<VersionedEntityInfo> listEntitiesAtVersion(TenantId tenantId, String versionId, String path) throws Exception;
|
||||
|
||||
@ -46,11 +49,13 @@ public interface GitRepositoryService {
|
||||
|
||||
VersionCreationResult push(PendingCommit commit);
|
||||
|
||||
void cleanUp(PendingCommit commit);
|
||||
|
||||
void abort(PendingCommit commit);
|
||||
|
||||
List<String> listBranches(TenantId tenantId);
|
||||
|
||||
String getFileContentAtCommit(TenantId tenantId, String relativePath, String versionId) throws IOException;
|
||||
|
||||
void fetch(TenantId tenantId);
|
||||
void fetch(TenantId tenantId) throws GitAPIException;
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ package org.thingsboard.server.service.sync.vc;
|
||||
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -27,6 +26,7 @@ public class PendingCommit {
|
||||
private final UUID txId;
|
||||
private final String nodeId;
|
||||
private final TenantId tenantId;
|
||||
private final String workingBranch;
|
||||
private String branch;
|
||||
private String versionName;
|
||||
|
||||
@ -36,5 +36,6 @@ public class PendingCommit {
|
||||
this.txId = txId;
|
||||
this.branch = branch;
|
||||
this.versionName = versionName;
|
||||
this.workingBranch = txId.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,13 +26,13 @@ VALUES ( '61441950-4612-11e7-a919-92ebcb67fe33', 1592576748000, '5a797660-4612-1
|
||||
'$2a$10$5JTB8/hxWc9WAy62nCGSxeefl3KWmipA9nFpVdDa0/xfIseeBB4Bu' );
|
||||
|
||||
/** System settings **/
|
||||
INSERT INTO admin_settings ( id, created_time, key, json_value )
|
||||
VALUES ( '6a2266e4-4612-11e7-a919-92ebcb67fe33', 1592576748000, 'general', '{
|
||||
INSERT INTO admin_settings ( id, created_time, tenant_id, key, json_value )
|
||||
VALUES ( '6a2266e4-4612-11e7-a919-92ebcb67fe33', 1592576748000, '13814000-1dd2-11b2-8080-808080808080', 'general', '{
|
||||
"baseUrl": "http://localhost:8080"
|
||||
}' );
|
||||
|
||||
INSERT INTO admin_settings ( id, created_time, key, json_value )
|
||||
VALUES ( '6eaaefa6-4612-11e7-a919-92ebcb67fe33', 1592576748000, 'mail', '{
|
||||
INSERT INTO admin_settings ( id, created_time, tenant_id, key, json_value )
|
||||
VALUES ( '6eaaefa6-4612-11e7-a919-92ebcb67fe33', 1592576748000, '13814000-1dd2-11b2-8080-808080808080', 'mail', '{
|
||||
"mailFrom": "Thingsboard <sysadmin@localhost.localdomain>",
|
||||
"smtpProtocol": "smtp",
|
||||
"smtpHost": "localhost",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user