Skip to content

Commit

Permalink
feat(index): support subjects in index commits
Browse files Browse the repository at this point in the history
They are either part of the current commit or supplied via the staging
area context. Denote resource and version documents as commit subjects.
  • Loading branch information
cmark committed Sep 22, 2023
1 parent fb1b863 commit e74a176
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ protected final <T extends Revision> T getRevision(final String branch, final Cl
return index().read(branch, index -> index.get(type, key));
}

protected final void indexRevision(final String branchPath, final Revision... revisions) {
commit(branchPath, Arrays.asList(revisions));
protected final Commit indexRevision(final String branchPath, final Revision... revisions) {
return commit(branchPath, Arrays.asList(revisions));
}

protected final <T extends Revision> Commit indexChange(final String branchPath, final T oldRevision, final T newRevision) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2023 B2i Healthcare Pte Ltd, https://b2i.sg
*
* 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
*
* 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.b2international.index.revision;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.junit.Test;

import com.b2international.index.Doc;

/**
* @since 9.0
*/
public class RevisionCommitSubjectTest extends BaseRevisionIndexTest {

@Doc
private static final class SubjectRevision extends Revision implements CommitSubject {

public SubjectRevision(String id) {
super(id);
}

@Override
public String extractSubjectId() {
return getId();
}

}

private static final class CommitSubjectSupplierImpl implements CommitSubjectSupplier {

@Override
public Set<String> getSubjectIds() {
return Set.of(STORAGE_KEY2);
}

}

@Override
protected Collection<Class<?>> getTypes() {
return List.of(SubjectRevision.class, RevisionFixtures.RevisionData.class);
}

@Test
public void commitSubject() throws Exception {
Commit commit = indexRevision(MAIN, new SubjectRevision(STORAGE_KEY1));
assertThat(commit.getSubjects()).containsOnly(STORAGE_KEY1);
}

@Test
public void commitSubjectSupplier() throws Exception {
Commit commit = index().prepareCommit(MAIN)
.withContext(new CommitSubjectSupplierImpl())
.stageNew(new RevisionFixtures.RevisionData(STORAGE_KEY1, "field1", "field2"))
.commit(currentTime(), USER_ID, "Commit");

assertThat(commit.getSubjects()).containsOnly(STORAGE_KEY2);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static final class Builder {
private String groupId;
private RevisionBranchPoint mergeSource;
private Boolean squashMerge;
private SortedSet<String> subjects;

public Builder id(final String id) {
this.id = id;
Expand All @@ -91,7 +92,7 @@ public Builder timestamp(final Long timestamp) {
return this;
}

public Builder groupId(String groupId) {
public Builder groupId(final String groupId) {
this.groupId = groupId;
return this;
}
Expand All @@ -106,13 +107,18 @@ public Builder mergeSource(final RevisionBranchPoint mergeSource) {
return this;
}

public Builder squashMerge(Boolean squashMerge) {
public Builder squashMerge(final Boolean squashMerge) {
this.squashMerge = squashMerge;
return this;
}

public Builder subjects(final SortedSet<String> subjects) {
this.subjects = subjects;
return this;
}

public Commit build() {
return new Commit(id, branch, author, comment, timestamp, groupId, details, mergeSource, squashMerge);
return new Commit(id, branch, author, comment, timestamp, groupId, details, mergeSource, squashMerge, subjects);
}

}
Expand Down Expand Up @@ -206,6 +212,9 @@ public static final class Fields {
public static final String MERGE_SOURCE = "mergeSource";
private static final String DETAILS_OBJECT = "details.objects";
private static final String DETAILS_COMPONENT = "details.components";

public static final String SUBJECTS = "subjects";

// Sort keys
public static final Set<String> ALL = ImmutableSet.of(BRANCH, AUTHOR, TIMESTAMP);
}
Expand All @@ -230,6 +239,8 @@ public static final class Fields {

private float score = 0.0f;

private final SortedSet<String> subjects;

@JsonIgnore
private transient Multimap<String, CommitDetail> detailsByObject;

Expand All @@ -242,7 +253,8 @@ private Commit(
final String groupId,
final List<CommitDetail> details,
final RevisionBranchPoint mergeSource,
final Boolean squashMerge) {
final Boolean squashMerge,
final SortedSet<String> subjects) {
this.id = id;
this.branch = branch;
this.author = author;
Expand All @@ -251,6 +263,7 @@ private Commit(
this.groupId = groupId;
this.mergeSource = mergeSource;
this.squashMerge = squashMerge;
this.subjects = subjects;
this.details = Collections3.toImmutableList(details);
}

Expand Down Expand Up @@ -301,6 +314,10 @@ public Boolean getSquashMerge() {
return squashMerge;
}

public SortedSet<String> getSubjects() {
return subjects;
}

@JsonIgnore
public boolean isMergeCommit() {
return mergeSource != null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 B2i Healthcare Pte Ltd, https://b2i.sg
*
* 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
*
* 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.b2international.index.revision;

/**
* Simple marker interface to denote a revision document as a subject of a commit and extract a unique identifier to identify the subject when extracting a {@link Commit}.
*
* @since 9.0
*/
public interface CommitSubject {

String extractSubjectId();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2023 B2i Healthcare Pte Ltd, https://b2i.sg
*
* 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
*
* 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.b2international.index.revision;

import java.util.Set;

/**
* Interface to use for {@link StagingArea} context objects when they'd like to populate external information in the {@link Commit} document's subjects array.
*/
public interface CommitSubjectSupplier {

Set<String> getSubjectIds();

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public final class StagingArea {
private SetMultimap<Class<?>, String> revisionsToReviseOnMergeSource;
private SetMultimap<Class<?>, String> externalRevisionsToReviseOnMergeSource;
private Object context;

StagingArea(DefaultRevisionIndex index, String branchPath, ObjectMapper mapper) {
this.index = index;
this.mappings = index.admin().mappings();
Expand Down Expand Up @@ -366,6 +366,7 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
final Multimap<ObjectId, ObjectId> changedComponentsByContainer = HashMultimap.create();
final Multimap<ObjectId, ObjectId> removedComponentsByContainer = HashMultimap.create();
final Multimap<Class<?>, String> deletedIdsByType = HashMultimap.create();
final SortedSet<String> subjects = new TreeSet<>();

stagedObjects.entrySet().forEach( entry -> {
ObjectId key = entry.getKey();
Expand Down Expand Up @@ -405,6 +406,9 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
if (isMerge()) {
revisionsToReviseOnMergeSource.put(document.getClass(), key.id());
}
if (rev instanceof CommitSubject subject) {
subjects.add(subject.extractSubjectId());
}
} else {
newComponentsByContainer.put(ObjectId.rootOf(DocumentMapping.getDocType(document.getClass())), key);
}
Expand All @@ -430,6 +434,10 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
revisionsToReviseOnMergeSource.put(rev.getClass(), rev.getId());
}

if (rev instanceof CommitSubject subject) {
subjects.add(subject.extractSubjectId());
}

writer.put(rev);

// register component as changed in commit doc
Expand Down Expand Up @@ -548,7 +556,7 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
} else {
details = Collections.emptyList();
}

// free up memory before committing
clear();
newComponentsByContainer.clear();
Expand All @@ -564,6 +572,11 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
// raise watermark logs if above thresholds
reportWarningIfCommitWatermarkExceeded(details, author, commitComment);

// make sure we populate subjects from the current supplied context, if it is a CommitSubjectSupplier
if (context instanceof CommitSubjectSupplier css) {
subjects.addAll(css.getSubjectIds());
}

// generate a commit entry that marks the end of the commit and contains all changes in a details property
Commit commitDoc = commit
.id(UUIDs.randomBase64UUID())
Expand All @@ -573,6 +586,7 @@ private Commit doCommit(String commitGroupId, long timestamp, String author, Str
.comment(commitComment)
.timestamp(timestamp)
.details(details)
.subjects(subjects)
.mergeSource(!CompareUtils.isEmpty(mergeSources) ? mergeSources.last() : null)
.squashMerge(!CompareUtils.isEmpty(mergeSources) ? squashMerge : null)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.b2international.index.mapping.FieldAlias;
import com.b2international.index.mapping.FieldAlias.FieldAliasType;
import com.b2international.index.query.Expression;
import com.b2international.index.revision.CommitSubject;
import com.b2international.index.revision.RevisionBranchPoint;
import com.b2international.snowowl.core.ResourceURI;
import com.b2international.snowowl.core.ResourceURIWithQuery;
Expand Down Expand Up @@ -66,7 +67,7 @@
@Script(
name="snomedFirst",
script="return (doc[\"toolingId\"].size() != 0 && doc.toolingId.value.equals(\"snomed\")) ? \"0\" : \"1\"")
public final class ResourceDocument extends RevisionDocument {
public final class ResourceDocument extends RevisionDocument implements CommitSubject {

public static final String TYPE = "resource";

Expand Down Expand Up @@ -675,4 +676,9 @@ public SortedSet<DependencyDocument> getDependencies() {
return dependencies;
}

@Override
public String extractSubjectId() {
return getResourceURI().toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.b2international.index.ID;
import com.b2international.index.mapping.Field;
import com.b2international.index.query.Expression;
import com.b2international.index.revision.CommitSubject;
import com.b2international.index.revision.RevisionBranch;
import com.b2international.index.revision.RevisionBranchPoint;
import com.b2international.snowowl.core.Dependency;
Expand All @@ -49,7 +50,7 @@
*/
@Doc(type = VersionDocument.TYPE)
@JsonDeserialize(builder = VersionDocument.Builder.class)
public final class VersionDocument implements Serializable {
public final class VersionDocument implements CommitSubject, Serializable {

private static final long serialVersionUID = 2L;

Expand Down Expand Up @@ -552,6 +553,11 @@ public SortedSet<DependencyDocument> getDependencies() {
return dependencies;
}

@Override
public String extractSubjectId() {
return getResource().toString();
}

// additional helpers

/**
Expand Down

0 comments on commit e74a176

Please sign in to comment.