Merge branch 'feature/entities-version-control' of github.com:thingsboard/thingsboard into feature/entities-version-control
This commit is contained in:
commit
bf03475987
@ -119,7 +119,7 @@ public class DefaultEntitiesVersionControlService implements EntitiesVersionCont
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@Override
|
||||
public ListenableFuture<VersionCreationResult> saveEntitiesVersion(SecurityUser user, VersionCreateRequest request) throws Exception {
|
||||
var pendingCommit = gitServiceQueue.prepareCommit(user.getTenantId(), request);
|
||||
var pendingCommit = gitServiceQueue.prepareCommit(user, request);
|
||||
|
||||
return transformAsync(pendingCommit, commit -> {
|
||||
List<ListenableFuture<Void>> gitFutures = new ArrayList<>();
|
||||
|
||||
@ -27,6 +27,7 @@ import org.thingsboard.server.cluster.TbClusterService;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
@ -66,10 +67,7 @@ import org.thingsboard.server.service.sync.vc.data.PendingGitRequest;
|
||||
import org.thingsboard.server.service.sync.vc.data.VersionsDiffGitRequest;
|
||||
import org.thingsboard.server.service.sync.vc.data.VoidGitRequest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@ -96,12 +94,12 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<CommitGitRequest> prepareCommit(TenantId tenantId, VersionCreateRequest request) {
|
||||
public ListenableFuture<CommitGitRequest> prepareCommit(User user, VersionCreateRequest request) {
|
||||
SettableFuture<CommitGitRequest> future = SettableFuture.create();
|
||||
|
||||
CommitGitRequest commit = new CommitGitRequest(tenantId, request);
|
||||
CommitGitRequest commit = new CommitGitRequest(user.getTenantId(), request);
|
||||
registerAndSend(commit, builder -> builder.setCommitRequest(
|
||||
buildCommitRequest(commit).setPrepareMsg(getCommitPrepareMsg(request)).build()
|
||||
buildCommitRequest(commit).setPrepareMsg(getCommitPrepareMsg(user, request)).build()
|
||||
).build(), wrap(future, commit));
|
||||
return future;
|
||||
}
|
||||
@ -356,7 +354,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
} else if (vcResponseMsg.hasCommitResponse()) {
|
||||
var commitResponse = vcResponseMsg.getCommitResponse();
|
||||
var commitResult = new VersionCreationResult();
|
||||
commitResult.setVersion(new EntityVersion(commitResponse.getTs(), commitResponse.getCommitId(), commitResponse.getName()));
|
||||
commitResult.setVersion(new EntityVersion(commitResponse.getTs(), commitResponse.getCommitId(), commitResponse.getName(), commitResponse.getAuthor()));
|
||||
commitResult.setAdded(commitResponse.getAdded());
|
||||
commitResult.setRemoved(commitResponse.getRemoved());
|
||||
commitResult.setModified(commitResponse.getModified());
|
||||
@ -405,7 +403,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
}
|
||||
|
||||
private EntityVersion getEntityVersion(TransportProtos.EntityVersionProto proto) {
|
||||
return new EntityVersion(proto.getTs(), proto.getId(), proto.getName());
|
||||
return new EntityVersion(proto.getTs(), proto.getId(), proto.getName(), proto.getAuthor());
|
||||
}
|
||||
|
||||
private VersionedEntityInfo getVersionedEntityInfo(TransportProtos.VersionedEntityInfoProto proto) {
|
||||
@ -453,8 +451,23 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
|
||||
return path;
|
||||
}
|
||||
|
||||
private static PrepareMsg getCommitPrepareMsg(VersionCreateRequest request) {
|
||||
return PrepareMsg.newBuilder().setCommitMsg(request.getVersionName()).setBranchName(request.getBranch()).build();
|
||||
private static PrepareMsg getCommitPrepareMsg(User user, VersionCreateRequest request) {
|
||||
return PrepareMsg.newBuilder().setCommitMsg(request.getVersionName())
|
||||
.setBranchName(request.getBranch()).setAuthorName(getAuthorName(user)).setAuthorEmail(user.getEmail()).build();
|
||||
}
|
||||
|
||||
private static String getAuthorName(User user) {
|
||||
List<String> parts = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(user.getFirstName())) {
|
||||
parts.add(user.getFirstName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(user.getLastName())) {
|
||||
parts.add(user.getLastName());
|
||||
}
|
||||
if (parts.isEmpty()) {
|
||||
parts.add(user.getName());
|
||||
}
|
||||
return String.join(" ", parts);
|
||||
}
|
||||
|
||||
private ToVersionControlServiceMsg.Builder newRequestProto(PendingGitRequest<?> request, RepositorySettings settings) {
|
||||
|
||||
@ -18,6 +18,7 @@ package org.thingsboard.server.service.sync.vc;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.ExportableEntity;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
@ -36,7 +37,7 @@ import java.util.List;
|
||||
|
||||
public interface GitVersionControlQueueService {
|
||||
|
||||
ListenableFuture<CommitGitRequest> prepareCommit(TenantId tenantId, VersionCreateRequest request);
|
||||
ListenableFuture<CommitGitRequest> prepareCommit(User user, VersionCreateRequest request);
|
||||
|
||||
ListenableFuture<Void> addToCommit(CommitGitRequest commit, EntityExportData<ExportableEntity<EntityId>> entityData);
|
||||
|
||||
|
||||
@ -692,14 +692,17 @@ message CommitResponseMsg {
|
||||
int64 ts = 1;
|
||||
string commitId = 2;
|
||||
string name = 3;
|
||||
int32 added = 4;
|
||||
int32 modified = 5;
|
||||
int32 removed = 6;
|
||||
string author = 4;
|
||||
int32 added = 5;
|
||||
int32 modified = 6;
|
||||
int32 removed = 7;
|
||||
}
|
||||
|
||||
message PrepareMsg {
|
||||
string commitMsg = 1;
|
||||
string branchName = 2;
|
||||
string authorName = 3;
|
||||
string authorEmail = 4;
|
||||
}
|
||||
|
||||
message AddMsg {
|
||||
@ -733,6 +736,7 @@ message EntityVersionProto {
|
||||
int64 ts = 1;
|
||||
string id = 2;
|
||||
string name = 3;
|
||||
string author = 4;
|
||||
}
|
||||
|
||||
message ListVersionsResponseMsg {
|
||||
|
||||
@ -26,4 +26,5 @@ public class EntityVersion {
|
||||
private long timestamp;
|
||||
private String id;
|
||||
private String name;
|
||||
private String author;
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
.setTotalElements(data.getTotalElements())
|
||||
.setHasNext(data.hasNext())
|
||||
.addAllVersions(data.getData().stream().map(
|
||||
v -> EntityVersionProto.newBuilder().setTs(v.getTimestamp()).setId(v.getId()).setName(v.getName()).build()
|
||||
v -> EntityVersionProto.newBuilder().setTs(v.getTimestamp()).setId(v.getId()).setName(v.getName()).setAuthor(v.getAuthor()).build()
|
||||
).collect(Collectors.toList())))
|
||||
);
|
||||
}
|
||||
@ -397,7 +397,8 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
|
||||
private void prepareCommit(VersionControlRequestCtx ctx, UUID txId, PrepareMsg prepareMsg) {
|
||||
var tenantId = ctx.getTenantId();
|
||||
var pendingCommit = new PendingCommit(tenantId, ctx.getNodeId(), txId, prepareMsg.getBranchName(), prepareMsg.getCommitMsg());
|
||||
var pendingCommit = new PendingCommit(tenantId, ctx.getNodeId(), txId, prepareMsg.getBranchName(),
|
||||
prepareMsg.getCommitMsg(), prepareMsg.getAuthorName(), prepareMsg.getAuthorEmail());
|
||||
PendingCommit old = pendingCommitMap.get(tenantId);
|
||||
if (old != null) {
|
||||
doAbortCurrentCommit(tenantId, old);
|
||||
@ -460,6 +461,7 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
|
||||
.setTs(result.getVersion().getTimestamp())
|
||||
.setCommitId(result.getVersion().getId())
|
||||
.setName(result.getVersion().getName())
|
||||
.setAuthor(result.getVersion().getAuthor())
|
||||
.setAdded(result.getAdded())
|
||||
.setModified(result.getModified())
|
||||
.setRemoved(result.getRemoved())));
|
||||
|
||||
@ -117,7 +117,7 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
result.setModified(status.getModified().size());
|
||||
result.setRemoved(status.getRemoved().size());
|
||||
|
||||
GitRepository.Commit gitCommit = repository.commit(commit.getVersionName());
|
||||
GitRepository.Commit gitCommit = repository.commit(commit.getVersionName(), commit.getAuthorName(), commit.getAuthorEmail());
|
||||
repository.push(commit.getWorkingBranch(), commit.getBranch());
|
||||
|
||||
result.setVersion(toVersion(gitCommit));
|
||||
@ -255,7 +255,15 @@ public class DefaultGitRepositoryService implements GitRepositoryService {
|
||||
}
|
||||
|
||||
private EntityVersion toVersion(GitRepository.Commit commit) {
|
||||
return new EntityVersion(commit.getTimestamp(), commit.getId(), commit.getMessage());
|
||||
return new EntityVersion(commit.getTimestamp(), commit.getId(), commit.getMessage(), this.getAuthor(commit));
|
||||
}
|
||||
|
||||
private String getAuthor(GitRepository.Commit commit) {
|
||||
String author = String.format("<%s>", commit.getAuthorEmail());
|
||||
if (StringUtils.isNotBlank(commit.getAuthorName())) {
|
||||
author = String.format("%s %s", commit.getAuthorName(), author);
|
||||
}
|
||||
return author;
|
||||
}
|
||||
|
||||
public static EntityId fromRelativePath(String path) {
|
||||
|
||||
@ -255,8 +255,9 @@ public class GitRepository {
|
||||
return new Status(status.getAdded(), modified, status.getRemoved());
|
||||
}
|
||||
|
||||
public Commit commit(String message) throws GitAPIException {
|
||||
public Commit commit(String message, String authorName, String authorEmail) throws GitAPIException {
|
||||
RevCommit revCommit = execute(git.commit()
|
||||
.setAuthor(authorName, authorEmail)
|
||||
.setMessage(message));
|
||||
return toCommit(revCommit);
|
||||
}
|
||||
@ -325,7 +326,8 @@ public class GitRepository {
|
||||
}
|
||||
|
||||
private Commit toCommit(RevCommit revCommit) {
|
||||
return new Commit(revCommit.getCommitTime() * 1000l, revCommit.getName(), revCommit.getFullMessage(), revCommit.getAuthorIdent().getName());
|
||||
return new Commit(revCommit.getCommitTime() * 1000l, revCommit.getName(),
|
||||
revCommit.getFullMessage(), revCommit.getAuthorIdent().getName(), revCommit.getAuthorIdent().getEmailAddress());
|
||||
}
|
||||
|
||||
private RevCommit resolveCommit(String id) throws IOException {
|
||||
@ -470,6 +472,7 @@ public class GitRepository {
|
||||
private final String id;
|
||||
private final String message;
|
||||
private final String authorName;
|
||||
private final String authorEmail;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
@ -30,12 +30,18 @@ public class PendingCommit {
|
||||
private String branch;
|
||||
private String versionName;
|
||||
|
||||
public PendingCommit(TenantId tenantId, String nodeId, UUID txId, String branch, String versionName) {
|
||||
private String authorName;
|
||||
|
||||
private String authorEmail;
|
||||
|
||||
public PendingCommit(TenantId tenantId, String nodeId, UUID txId, String branch, String versionName, String authorName, String authorEmail) {
|
||||
this.tenantId = tenantId;
|
||||
this.nodeId = nodeId;
|
||||
this.txId = txId;
|
||||
this.branch = branch;
|
||||
this.versionName = versionName;
|
||||
this.authorName = authorName;
|
||||
this.authorEmail = authorEmail;
|
||||
this.workingBranch = txId.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,11 +101,17 @@
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef style="width: 100%"> {{ 'version-control.version-name' | translate }} </mat-header-cell>
|
||||
<mat-header-cell *matHeaderCellDef style="width: 50%"> {{ 'version-control.version-name' | translate }} </mat-header-cell>
|
||||
<mat-cell *matCellDef="let entityVersion">
|
||||
{{ entityVersion.name }}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="author">
|
||||
<mat-header-cell *matHeaderCellDef style="width: 50%"> {{ 'version-control.author' | translate }} </mat-header-cell>
|
||||
<mat-cell *matCellDef="let entityVersion">
|
||||
{{ entityVersion.author }}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions" stickyEnd>
|
||||
<mat-header-cell *matHeaderCellDef [ngStyle]="singleEntityMode ? {minWidth: '80px', maxWidth: '80px', width: '80px'} :
|
||||
{minWidth: '40px', maxWidth: '40px', width: '40px'}">
|
||||
|
||||
@ -62,7 +62,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni
|
||||
@Input()
|
||||
singleEntityMode = false;
|
||||
|
||||
displayedColumns = ['timestamp', 'id', 'name', 'actions'];
|
||||
displayedColumns = ['timestamp', 'id', 'name', 'author', 'actions'];
|
||||
pageLink: PageLink;
|
||||
textSearchMode = false;
|
||||
dataSource: EntityVersionsDatasource;
|
||||
|
||||
@ -138,6 +138,7 @@ export interface EntityVersion {
|
||||
timestamp: number;
|
||||
id: string;
|
||||
name: string;
|
||||
author: string;
|
||||
}
|
||||
|
||||
export interface VersionCreationResult {
|
||||
|
||||
@ -3119,6 +3119,7 @@
|
||||
"create-entity-version": "Create entity version",
|
||||
"version-name": "Version name",
|
||||
"version-name-required": "Version name is required",
|
||||
"author": "Author",
|
||||
"export-entity-relations": "Export entity relations",
|
||||
"entity-versions": "Entity versions",
|
||||
"versions": "Versions",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user