From 472357109dce21ed3aabcc30b747acfb962339e0 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 23 Jun 2022 14:12:03 +0300 Subject: [PATCH] VC: Detect default remote branch. Fix Entities Version Control REST API mappings to handle branch parameter. --- .../EntitiesVersionControlController.java | 68 +++++++++---------- .../DefaultEntitiesVersionControlService.java | 5 +- .../DefaultGitVersionControlQueueService.java | 9 ++- .../vc/EntitiesVersionControlService.java | 11 ++- .../vc/GitVersionControlQueueService.java | 7 +- .../sync/vc/data/ListBranchesGitRequest.java | 3 +- common/cluster-api/src/main/proto/queue.proto | 7 +- .../common/data/sync/vc/BranchInfo.java | 39 +++++++++++ .../DefaultClusterVersionControlService.java | 6 +- .../sync/vc/DefaultGitRepositoryService.java | 7 +- .../server/service/sync/vc/GitRepository.java | 31 +++++++-- .../service/sync/vc/GitRepositoryService.java | 5 +- .../http/entities-version-control.service.ts | 12 ++-- 13 files changed, 142 insertions(+), 68 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/BranchInfo.java diff --git a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java index 1bcc304548..fff3c6a4bb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java @@ -20,7 +20,6 @@ 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.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; @@ -39,6 +38,7 @@ 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.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityDataDiff; import org.thingsboard.server.common.data.sync.vc.EntityDataInfo; import org.thingsboard.server.common.data.sync.vc.EntityVersion; @@ -56,6 +56,7 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; @@ -138,10 +139,10 @@ public class EntitiesVersionControlController extends BaseController { " \"name\": \"Device profile 1 version 1.0\"\n" + " }\n" + "]\n```") - @GetMapping(value = "/version/{branch}/{entityType}/{externalEntityUuid}", params = {"pageSize", "page"}) - public DeferredResult> listEntityVersions(@PathVariable String branch, - @PathVariable EntityType entityType, + @GetMapping(value = "/version/{entityType}/{externalEntityUuid}", params = {"branch", "pageSize", "page"}) + public DeferredResult> listEntityVersions(@PathVariable EntityType entityType, @PathVariable UUID externalEntityUuid, + @RequestParam String branch, @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @@ -165,9 +166,9 @@ public class EntitiesVersionControlController extends BaseController { " \"name\": \"Device profiles from dev\"\n" + " }\n" + "]\n```") - @GetMapping(value = "/version/{branch}/{entityType}", params = {"pageSize", "page"}) - public DeferredResult> listEntityTypeVersions(@PathVariable String branch, - @PathVariable EntityType entityType, + @GetMapping(value = "/version/{entityType}", params = {"branch", "pageSize", "page"}) + public DeferredResult> listEntityTypeVersions(@PathVariable EntityType entityType, + @RequestParam String branch, @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @@ -198,8 +199,8 @@ public class EntitiesVersionControlController extends BaseController { " \"name\": \"Devices added\"\n" + " }\n" + "]\n```") - @GetMapping(value = "/version/{branch}", params = {"pageSize", "page"}) - public DeferredResult> listVersions(@PathVariable String branch, + @GetMapping(value = "/version", params = {"branch", "pageSize", "page"}) + public DeferredResult> listVersions(@RequestParam String branch, @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @@ -216,17 +217,17 @@ public class EntitiesVersionControlController extends BaseController { } - @GetMapping("/entity/{branch}/{entityType}/{versionId}") - public DeferredResult> listEntitiesAtVersion(@PathVariable String branch, - @PathVariable EntityType entityType, - @PathVariable String versionId) throws Exception { + @GetMapping(value = "/entity/{entityType}/{versionId}", params = {"branch"}) + public DeferredResult> listEntitiesAtVersion(@PathVariable EntityType entityType, + @PathVariable String versionId, + @RequestParam String branch) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listEntitiesAtVersion(getTenantId(), branch, versionId, entityType)); } - @GetMapping("/entity/{branch}/{versionId}") - public DeferredResult> listAllEntitiesAtVersion(@PathVariable String branch, - @PathVariable String versionId) throws Exception { + @GetMapping(value = "/entity/{versionId}", params = {"branch"}) + public DeferredResult> listAllEntitiesAtVersion(@PathVariable String versionId, + @RequestParam String branch) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listAllEntitiesAtVersion(getTenantId(), branch, versionId)); } @@ -240,10 +241,10 @@ public class EntitiesVersionControlController extends BaseController { return wrapFuture(versionControlService.getEntityDataInfo(getCurrentUser(), entityId, versionId)); } - @GetMapping("/diff/{branch}/{entityType}/{internalEntityUuid}") - public DeferredResult compareEntityDataToVersion(@PathVariable String branch, - @PathVariable EntityType entityType, + @GetMapping(value = "/diff/{entityType}/{internalEntityUuid}", params = {"branch", "versionId"}) + public DeferredResult compareEntityDataToVersion(@PathVariable EntityType entityType, @PathVariable UUID internalEntityUuid, + @RequestParam String branch, @RequestParam String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, internalEntityUuid); @@ -318,20 +319,21 @@ public class EntitiesVersionControlController extends BaseController { try { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); final TenantId tenantId = getTenantId(); - ListenableFuture> branches = versionControlService.listBranches(tenantId); + ListenableFuture> branches = versionControlService.listBranches(tenantId); return wrapFuture(Futures.transform(branches, remoteBranches -> { List infos = new ArrayList<>(); - - String defaultBranch = versionControlService.getVersionControlSettings(tenantId).getDefaultBranch(); - if (StringUtils.isNotEmpty(defaultBranch)) { - infos.add(new BranchInfo(defaultBranch, true)); + BranchInfo defaultBranch; + String defaultBranchName = versionControlService.getVersionControlSettings(tenantId).getDefaultBranch(); + if (StringUtils.isNotEmpty(defaultBranchName)) { + defaultBranch = new BranchInfo(defaultBranchName, true); + } else { + defaultBranch = remoteBranches.stream().filter(BranchInfo::isDefault).findFirst().orElse(null); } - - remoteBranches.forEach(branch -> { - if (!branch.equals(defaultBranch)) { - infos.add(new BranchInfo(branch, false)); - } - }); + if (defaultBranch != null) { + infos.add(defaultBranch); + } + infos.addAll(remoteBranches.stream().filter(b -> !b.equals(defaultBranch)) + .map(b -> new BranchInfo(b.getName(), false)).collect(Collectors.toList())); return infos; }, MoreExecutors.directExecutor())); } catch (Exception e) { @@ -339,10 +341,4 @@ public class EntitiesVersionControlController extends BaseController { } } - @Data - public static class BranchInfo { - private final String name; - private final boolean isDefault; - } - } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java index 6ea8115e53..3b625fc086 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java @@ -25,12 +25,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.TbStopWatch; import org.thingsboard.common.util.ThingsBoardExecutors; -import org.thingsboard.server.cache.CaffeineTbTransactionalCache; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ExportableEntity; @@ -49,6 +47,7 @@ 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; import org.thingsboard.server.common.data.sync.ie.EntityImportSettings; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityDataDiff; import org.thingsboard.server.common.data.sync.vc.EntityDataInfo; import org.thingsboard.server.common.data.sync.vc.EntityLoadError; @@ -479,7 +478,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont @Override - public ListenableFuture> listBranches(TenantId tenantId) throws Exception { + public ListenableFuture> listBranches(TenantId tenantId) throws Exception { return gitServiceQueue.listBranches(tenantId); } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java index 99246d282f..628605824e 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java @@ -35,6 +35,7 @@ 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.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityVersion; import org.thingsboard.server.common.data.sync.vc.EntityVersionsDiff; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; @@ -240,7 +241,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu } @Override - public ListenableFuture> listBranches(TenantId tenantId) { + public ListenableFuture> listBranches(TenantId tenantId) { ListBranchesGitRequest request = new ListBranchesGitRequest(tenantId); return sendRequest(request, builder -> builder.setListBranchesRequest(TransportProtos.ListBranchesRequestMsg.newBuilder().build())); } @@ -382,7 +383,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu ((CommitGitRequest) request).getFuture().set(commitResult); } else if (vcResponseMsg.hasListBranchesResponse()) { var listBranchesResponse = vcResponseMsg.getListBranchesResponse(); - ((ListBranchesGitRequest) request).getFuture().set(listBranchesResponse.getBranchesList()); + ((ListBranchesGitRequest) request).getFuture().set(listBranchesResponse.getBranchesList().stream().map(this::getBranchInfo).collect(Collectors.toList())); } else if (vcResponseMsg.hasListEntitiesResponse()) { var listEntitiesResponse = vcResponseMsg.getListEntitiesResponse(); ((ListEntitiesGitRequest) request).getFuture().set( @@ -439,6 +440,10 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu return new VersionedEntityInfo(EntityIdFactory.getByTypeAndUuid(proto.getEntityType(), new UUID(proto.getEntityIdMSB(), proto.getEntityIdLSB()))); } + private BranchInfo getBranchInfo(TransportProtos.BranchInfoProto proto) { + return new BranchInfo(proto.getName(), proto.getIsDefault()); + } + @SuppressWarnings("rawtypes") @SneakyThrows private EntityExportData toData(String data) { diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java index 3ae68e33d0..5aa4c40008 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/EntitiesVersionControlService.java @@ -16,22 +16,21 @@ package org.thingsboard.server.service.sync.vc; import com.google.common.util.concurrent.ListenableFuture; -import org.springframework.web.context.request.async.DeferredResult; 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.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityDataDiff; import org.thingsboard.server.common.data.sync.vc.EntityDataInfo; -import org.thingsboard.server.common.data.sync.vc.VersionLoadResult; -import org.thingsboard.server.service.security.model.SecurityUser; -import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.EntityVersion; +import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.VersionCreationResult; -import org.thingsboard.server.common.data.sync.vc.EntityTypeLoadResult; +import org.thingsboard.server.common.data.sync.vc.VersionLoadResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; +import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest; import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest; @@ -60,7 +59,7 @@ public interface EntitiesVersionControlService { ListenableFuture compareEntityDataToVersion(SecurityUser user, String branch, EntityId entityId, String versionId) throws Exception; - ListenableFuture> listBranches(TenantId tenantId) throws Exception; + ListenableFuture> listBranches(TenantId tenantId) throws Exception; RepositorySettings getVersionControlSettings(TenantId tenantId); diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/GitVersionControlQueueService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/GitVersionControlQueueService.java index a1aad04701..a1e64da8f1 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/GitVersionControlQueueService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/GitVersionControlQueueService.java @@ -24,14 +24,15 @@ 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.RepositorySettings; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityVersion; +import org.thingsboard.server.common.data.sync.vc.EntityVersionsDiff; +import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.VersionCreationResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest; import org.thingsboard.server.gen.transport.TransportProtos.VersionControlResponseMsg; import org.thingsboard.server.service.sync.vc.data.CommitGitRequest; -import org.thingsboard.server.common.data.sync.vc.EntityVersionsDiff; import java.util.List; @@ -55,7 +56,7 @@ public interface GitVersionControlQueueService { ListenableFuture> listEntitiesAtVersion(TenantId tenantId, String branch, String versionId); - ListenableFuture> listBranches(TenantId tenantId); + ListenableFuture> listBranches(TenantId tenantId); ListenableFuture getEntity(TenantId tenantId, String versionId, EntityId entityId); diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/data/ListBranchesGitRequest.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/data/ListBranchesGitRequest.java index c045030dc7..4d89efa14d 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/data/ListBranchesGitRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/data/ListBranchesGitRequest.java @@ -16,10 +16,11 @@ package org.thingsboard.server.service.sync.vc.data; import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import java.util.List; -public class ListBranchesGitRequest extends PendingGitRequest> { +public class ListBranchesGitRequest extends PendingGitRequest> { public ListBranchesGitRequest(TenantId tenantId) { super(tenantId); diff --git a/common/cluster-api/src/main/proto/queue.proto b/common/cluster-api/src/main/proto/queue.proto index 3079978bce..b7362c7f03 100644 --- a/common/cluster-api/src/main/proto/queue.proto +++ b/common/cluster-api/src/main/proto/queue.proto @@ -765,8 +765,13 @@ message ListEntitiesResponseMsg { message ListBranchesRequestMsg { } +message BranchInfoProto { + string name = 1; + bool isDefault = 2; +} + message ListBranchesResponseMsg { - repeated string branches = 1; + repeated BranchInfoProto branches = 1; } message EntityContentRequestMsg { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/BranchInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/BranchInfo.java new file mode 100644 index 0000000000..fcf1f4470e --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/vc/BranchInfo.java @@ -0,0 +1,39 @@ +/** + * Copyright © 2016-2022 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.common.data.sync.vc; + +import lombok.Data; + +import java.util.Objects; + +@Data +public class BranchInfo { + private final String name; + private final boolean isDefault; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BranchInfo that = (BranchInfo) o; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java index b28618372e..f74f18ddaa 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java @@ -42,6 +42,7 @@ 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.AddMsg; +import org.thingsboard.server.gen.transport.TransportProtos.BranchInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.CommitRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.CommitResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.DeleteMsg; @@ -332,7 +333,10 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe } private void handleListBranches(VersionControlRequestCtx ctx, ListBranchesRequestMsg request) { - var branches = vcService.listBranches(ctx.getTenantId()); + var branches = vcService.listBranches(ctx.getTenantId()).stream() + .map(branchInfo -> BranchInfoProto.newBuilder() + .setName(branchInfo.getName()) + .setIsDefault(branchInfo.isDefault()).build()).collect(Collectors.toList()); reply(ctx, Optional.empty(), builder -> builder.setListBranchesResponse(ListBranchesResponseMsg.newBuilder().addAllBranches(branches))); } diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java index 99dbebc3c9..d3615f7228 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java @@ -29,8 +29,9 @@ 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.RepositorySettings; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityVersion; +import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.VersionCreationResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.service.sync.vc.GitRepository.Diff; @@ -84,7 +85,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService { repository.createAndCheckoutOrphanBranch(commit.getWorkingBranch()); repository.resetAndClean(); - if (repository.listRemoteBranches().contains(branch)) { + if (repository.listRemoteBranches().contains(new BranchInfo(branch, false))) { repository.merge(branch); } } catch (IOException | GitAPIException gitAPIException) { @@ -182,7 +183,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService { } @Override - public List listBranches(TenantId tenantId) { + public List listBranches(TenantId tenantId) { GitRepository repository = checkRepository(tenantId); try { return repository.listRemoteBranches(); diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 2b2802d003..392c686a14 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -41,10 +41,12 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.transport.CredentialsProvider; +import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.SshTransport; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; @@ -58,6 +60,7 @@ import org.eclipse.jgit.treewalk.filter.PathFilter; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod; @@ -69,7 +72,12 @@ import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.security.KeyPair; import java.security.PublicKey; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -84,6 +92,8 @@ public class GitRepository { @Getter private final String directory; + private ObjectId headId; + private GitRepository(Git git, RepositorySettings settings, CredentialsProvider credentialsProvider, SshdSessionFactory sshSessionFactory, String directory) { this.git = git; this.settings = settings; @@ -135,8 +145,12 @@ public class GitRepository { } public void fetch() throws GitAPIException { - execute(git.fetch() + FetchResult result = execute(git.fetch() .setRemoveDeletedRefs(true)); + Ref head = result.getAdvertisedRef(Constants.HEAD); + if (head != null) { + this.headId = head.getObjectId(); + } } public void deleteLocalBranchIfExists(String branch) throws GitAPIException { @@ -162,13 +176,11 @@ public class GitRepository { .include(branchId)); } - - public List listRemoteBranches() throws GitAPIException { + public List listRemoteBranches() throws GitAPIException { return execute(git.branchList() .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/")) + .map(this::toBranchInfo) .distinct().collect(Collectors.toList()); } @@ -325,6 +337,13 @@ public class GitRepository { .collect(Collectors.toList()); } + private BranchInfo toBranchInfo(Ref ref) { + String name = org.eclipse.jgit.lib.Repository.shortenRefName(ref.getName()); + String branchName = StringUtils.removeStart(name, "origin/"); + boolean isDefault = this.headId != null && this.headId.equals(ref.getObjectId()); + return new BranchInfo(branchName, isDefault); + } + private Commit toCommit(RevCommit revCommit) { return new Commit(revCommit.getCommitTime() * 1000l, revCommit.getName(), revCommit.getFullMessage(), revCommit.getAuthorIdent().getName(), revCommit.getAuthorIdent().getEmailAddress()); diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepositoryService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepositoryService.java index 057fa9c1ab..d4f909df9e 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepositoryService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepositoryService.java @@ -19,8 +19,9 @@ 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.RepositorySettings; +import org.thingsboard.server.common.data.sync.vc.BranchInfo; import org.thingsboard.server.common.data.sync.vc.EntityVersion; +import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.VersionCreationResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.service.sync.vc.GitRepository.Diff; @@ -57,7 +58,7 @@ public interface GitRepositoryService { void abort(PendingCommit commit); - List listBranches(TenantId tenantId); + List listBranches(TenantId tenantId); String getFileContentAtCommit(TenantId tenantId, String relativePath, String versionId) throws IOException; diff --git a/ui-ngx/src/app/core/http/entities-version-control.service.ts b/ui-ngx/src/app/core/http/entities-version-control.service.ts index ec0b6ba2ae..d7e892f1db 100644 --- a/ui-ngx/src/app/core/http/entities-version-control.service.ts +++ b/ui-ngx/src/app/core/http/entities-version-control.service.ts @@ -118,20 +118,23 @@ export class EntitiesVersionControlService { public listEntityVersions(pageLink: PageLink, branch: string, externalEntityId: EntityId, config?: RequestConfig): Observable> { - return this.http.get>(`/api/entities/vc/version/${branch}/${externalEntityId.entityType}/${externalEntityId.id}${pageLink.toQuery()}`, + const encodedBranch = encodeURIComponent(branch); + return this.http.get>(`/api/entities/vc/version/${externalEntityId.entityType}/${externalEntityId.id}${pageLink.toQuery()}&branch=${encodedBranch}`, defaultHttpOptionsFromConfig(config)); } public listEntityTypeVersions(pageLink: PageLink, branch: string, entityType: EntityType, config?: RequestConfig): Observable> { - return this.http.get>(`/api/entities/vc/version/${branch}/${entityType}${pageLink.toQuery()}`, + const encodedBranch = encodeURIComponent(branch); + return this.http.get>(`/api/entities/vc/version/${entityType}${pageLink.toQuery()}&branch=${encodedBranch}`, defaultHttpOptionsFromConfig(config)); } public listVersions(pageLink: PageLink, branch: string, config?: RequestConfig): Observable> { - return this.http.get>(`/api/entities/vc/version/${branch}${pageLink.toQuery()}`, + const encodedBranch = encodeURIComponent(branch); + return this.http.get>(`/api/entities/vc/version${pageLink.toQuery()}&branch=${encodedBranch}`, defaultHttpOptionsFromConfig(config)); } @@ -160,7 +163,8 @@ export class EntitiesVersionControlService { entityId: EntityId, versionId: string, config?: RequestConfig): Observable { - return this.http.get(`/api/entities/vc/diff/${branch}/${entityId.entityType}/${entityId.id}?versionId=${versionId}`, + const encodedBranch = encodeURIComponent(branch); + return this.http.get(`/api/entities/vc/diff/${entityId.entityType}/${entityId.id}?branch=${encodedBranch}&versionId=${versionId}`, defaultHttpOptionsFromConfig(config)); }