diff --git a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/AbstractCommitExecutor.java b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/CommitExecutor.java similarity index 93% rename from server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/AbstractCommitExecutor.java rename to server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/CommitExecutor.java index 19e029a55..bfd2ae892 100644 --- a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/AbstractCommitExecutor.java +++ b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/CommitExecutor.java @@ -23,6 +23,7 @@ import static java.util.Objects.requireNonNull; import java.util.List; +import java.util.function.Function; import javax.annotation.Nullable; @@ -51,7 +52,7 @@ import com.linecorp.centraldogma.server.command.CommitResult; import com.linecorp.centraldogma.server.storage.StorageException; -abstract class AbstractCommitExecutor { +final class CommitExecutor { final GitRepository gitRepository; private final long commitTimeMillis; @@ -61,8 +62,8 @@ abstract class AbstractCommitExecutor { private final Markup markup; private final boolean allowEmptyCommit; - AbstractCommitExecutor(GitRepository gitRepository, long commitTimeMillis, Author author, - String summary, String detail, Markup markup, boolean allowEmptyCommit) { + CommitExecutor(GitRepository gitRepository, long commitTimeMillis, Author author, + String summary, String detail, Markup markup, boolean allowEmptyCommit) { this.gitRepository = gitRepository; this.commitTimeMillis = commitTimeMillis; this.author = author; @@ -80,7 +81,12 @@ String summary() { return summary; } - CommitResult execute(Revision baseRevision) { + void executeInitialCommit(Iterable> changes) { + commit(null, Revision.INIT, changes); + } + + CommitResult execute(Revision baseRevision, + Function>> applyingChangesProvider) { final RevisionAndEntries res; final Iterable> applyingChanges; gitRepository.writeLock(); @@ -93,7 +99,7 @@ CommitResult execute(Revision baseRevision) { " or equivalent)"); } - applyingChanges = getOrCreateApplyingChanges(normBaseRevision); + applyingChanges = applyingChangesProvider.apply(normBaseRevision); res = commit(headRevision, headRevision.forward(1), applyingChanges); gitRepository.setHeadRevision(res.revision); @@ -106,8 +112,6 @@ CommitResult execute(Revision baseRevision) { return CommitResult.of(res.revision, applyingChanges); } - abstract Iterable> getOrCreateApplyingChanges(Revision normBaseRevision); - RevisionAndEntries commit(@Nullable Revision prevRevision, Revision nextRevision, Iterable> changes) { requireNonNull(nextRevision, "nextRevision"); diff --git a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/DefaultCommitExecutor.java b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/DefaultCommitExecutor.java deleted file mode 100644 index e83673190..000000000 --- a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/DefaultCommitExecutor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2024 LINE Corporation - * - * LINE Corporation licenses this file to you 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: - * - * https://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 com.linecorp.centraldogma.server.internal.storage.repository.git; - -import com.linecorp.centraldogma.common.Author; -import com.linecorp.centraldogma.common.Change; -import com.linecorp.centraldogma.common.Markup; -import com.linecorp.centraldogma.common.Revision; - -final class DefaultCommitExecutor extends AbstractCommitExecutor { - private final boolean directExecution; - private final Iterable> changes; - - DefaultCommitExecutor(GitRepository gitRepository, long commitTimeMillis, - Author author, String summary, String detail, - Markup markup, boolean allowEmptyCommit, - boolean directExecution, Iterable> changes) { - super(gitRepository, commitTimeMillis, author, summary, detail, markup, allowEmptyCommit); - this.directExecution = directExecution; - this.changes = changes; - } - - void executeInitialCommit() { - commit(null, Revision.INIT, changes); - } - - @Override - Iterable> getOrCreateApplyingChanges(Revision normBaseRevision) { - if (!directExecution) { - return changes; - } - return gitRepository.blockingPreviewDiff(normBaseRevision, new DefaultChangesApplier(changes)) - .values(); - } -} diff --git a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/GitRepository.java b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/GitRepository.java index 04f8a9e9f..97087c954 100644 --- a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/GitRepository.java +++ b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/GitRepository.java @@ -44,6 +44,7 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.BiConsumer; +import java.util.function.Function; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -246,9 +247,9 @@ class GitRepository implements Repository { // Initialize the commit ID database. commitIdDatabase = new CommitIdDatabase(jGitRepository); - new DefaultCommitExecutor(this, creationTimeMillis, author, "Create a new repository", "", - Markup.PLAINTEXT, true, false, Collections.emptyList()) - .executeInitialCommit(); + new CommitExecutor(this, creationTimeMillis, author, "Create a new repository", "", + Markup.PLAINTEXT, true) + .executeInitialCommit(Collections.emptyList()); headRevision = Revision.INIT; success = true; @@ -853,10 +854,14 @@ public CompletableFuture commit( requireNonNull(detail, "detail"); requireNonNull(markup, "markup"); requireNonNull(changes, "changes"); - final DefaultCommitExecutor commitExecutor = - new DefaultCommitExecutor(this, commitTimeMillis, author, summary, detail, - markup, false, directExecution, changes); - return commit(baseRevision, commitExecutor); + final CommitExecutor commitExecutor = + new CommitExecutor(this, commitTimeMillis, author, summary, detail, markup, false); + return commit(baseRevision, commitExecutor, normBaseRevision -> { + if (!directExecution) { + return changes; + } + return blockingPreviewDiff(normBaseRevision, new DefaultChangesApplier(changes)).values(); + }); } @Override @@ -869,19 +874,22 @@ public CompletableFuture commit(Revision baseRevision, long commit requireNonNull(detail, "detail"); requireNonNull(markup, "markup"); requireNonNull(transformer, "transformer"); - final TransformingCommitExecutor commitExecutor = - new TransformingCommitExecutor(this, commitTimeMillis, author, summary, - detail, markup, transformer); - return commit(baseRevision, commitExecutor); + final CommitExecutor commitExecutor = + new CommitExecutor(this, commitTimeMillis, author, summary, detail, markup, false); + return commit(baseRevision, commitExecutor, + normBaseRevision -> blockingPreviewDiff( + normBaseRevision, new TransformingChangesApplier(transformer)).values()); } - private CompletableFuture commit(Revision baseRevision, - AbstractCommitExecutor commitExecutor) { + private CompletableFuture commit( + Revision baseRevision, + CommitExecutor commitExecutor, + Function>> applyingChangesProvider) { final ServiceRequestContext ctx = context(); return CompletableFuture.supplyAsync(() -> { failFastIfTimedOut(this, logger, ctx, "commit", baseRevision, commitExecutor.author(), commitExecutor.summary()); - return commitExecutor.execute(baseRevision); + return commitExecutor.execute(baseRevision, applyingChangesProvider); }, repositoryWorker); } @@ -1306,16 +1314,18 @@ public void cloneTo(File newRepoDir, BiConsumer progressListen diff(previousNonEmptyRevision, revision, ALL_PATH).join().values(); try { - new DefaultCommitExecutor(newRepo, c.when(), c.author(), c.summary(), - c.detail(), c.markup(), false, false, changes) - .execute(baseRevision); + new CommitExecutor(newRepo, c.when(), c.author(), c.summary(), + c.detail(), c.markup(), false) + .execute(baseRevision, normBaseRevision -> blockingPreviewDiff( + normBaseRevision, new DefaultChangesApplier(changes)).values()); previousNonEmptyRevision = revision; } catch (RedundantChangeException e) { // NB: We allow an empty commit here because an old version of Central Dogma had a bug // which allowed the creation of an empty commit. - new DefaultCommitExecutor(newRepo, c.when(), c.author(), c.summary(), - c.detail(), c.markup(), true, false, changes) - .execute(baseRevision); + new CommitExecutor(newRepo, c.when(), c.author(), c.summary(), + c.detail(), c.markup(), true) + .execute(baseRevision, normBaseRevision -> blockingPreviewDiff( + normBaseRevision, new DefaultChangesApplier(changes)).values()); } progressListener.accept(i, endRevision.major()); diff --git a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/TransformingCommitExecutor.java b/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/TransformingCommitExecutor.java deleted file mode 100644 index c3e5ebd34..000000000 --- a/server/src/main/java/com/linecorp/centraldogma/server/internal/storage/repository/git/TransformingCommitExecutor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2024 LINE Corporation - * - * LINE Corporation licenses this file to you 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: - * - * https://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 com.linecorp.centraldogma.server.internal.storage.repository.git; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.fasterxml.jackson.databind.JsonNode; - -import com.linecorp.centraldogma.common.Author; -import com.linecorp.centraldogma.common.Change; -import com.linecorp.centraldogma.common.EntryType; -import com.linecorp.centraldogma.common.Markup; -import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.server.command.ContentTransformer; - -final class TransformingCommitExecutor extends AbstractCommitExecutor { - - private final ContentTransformer transformer; - - TransformingCommitExecutor(GitRepository gitRepository, long commitTimeMillis, - Author author, String summary, String detail, - Markup markup, ContentTransformer transformer) { - super(gitRepository, commitTimeMillis, author, summary, detail, markup, false); - checkArgument(transformer.entryType() == EntryType.JSON, - "transformer: %s (expected: JSON type)", transformer); - //noinspection unchecked - this.transformer = (ContentTransformer) transformer; - } - - @Override - Iterable> getOrCreateApplyingChanges(Revision normBaseRevision) { - return gitRepository.blockingPreviewDiff(normBaseRevision, new TransformingChangesApplier(transformer)) - .values(); - } -}