Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/SOLR-6973-signature-partial-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: SignatureUpdateProcessorFactory no longer adds an empty signature to (or deletes duplicates for) a partial update that contains none of the signature fields.
type: fixed
authors:
- name: Nick Shanin
links:
- name: SOLR-6973
url: https://issues.apache.org/jira/browse/SOLR-6973
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,29 @@ public void processAdd(AddUpdateCommand cmd) throws IOException {
currDocSigFields = sigFields;
}

if (isPartialUpdate) {
for (String field : currDocSigFields) {
if (doc.getField(field) != null) {
throw new SolrException(
ErrorCode.SERVER_ERROR,
"Can't use SignatureUpdateProcessor with partial update request "
+ "containing signature field: "
+ field);
}
}
// none of the signature fields are in the partial update, so there is nothing to sign;
// an empty signature would overwrite or delete unrelated documents
if (next != null) next.processAdd(cmd);
return;
}

Signature sig =
req.getCore().getResourceLoader().newInstance(signatureClass, Signature.class);
sig.init(params);

for (String field : currDocSigFields) {
SolrInputField f = doc.getField(field);
if (f != null) {
if (isPartialUpdate) {
throw new SolrException(
ErrorCode.SERVER_ERROR,
"Can't use SignatureUpdateProcessor with partial update request "
+ "containing signature field: "
+ field);
}
sig.add(field);
Object o = f.getValue();
if (o instanceof Collection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.lucene.util.Constants;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.request.JavaBinRequestWriter;
Expand All @@ -34,6 +35,7 @@
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryRequestBase;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.update.AddUpdateCommand;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
Expand Down Expand Up @@ -200,6 +202,39 @@ public void run() {
checkNumDocs(1);
}

@Test
public void testPartialUpdateWithoutSignatureFieldsIsPassedThrough() throws Exception {
SignatureUpdateProcessorFactory factory = new SignatureUpdateProcessorFactory();
NamedList<Object> args = new NamedList<>();
args.add("signatureField", "signatureField");
args.add("overwriteDupes", true);
args.add("fields", "v_t,t_field");
args.add("signatureClass", "org.apache.solr.update.processor.Lookup3Signature");
factory.init(args);

AtomicReference<AddUpdateCommand> seen = new AtomicReference<>();
try (SolrQueryRequest r = req()) {
UpdateRequestProcessor proc =
factory.getInstance(
r,
new SolrQueryResponse(),
new UpdateRequestProcessor(null) {
@Override
public void processAdd(AddUpdateCommand cmd) {
seen.set(cmd);
}
});
AddUpdateCommand cmd = new AddUpdateCommand(r);
cmd.solrDoc = new SolrInputDocument();
cmd.solrDoc.addField("id", "1a");
cmd.solrDoc.addField("name", Map.of("set", "changed"));
proc.processAdd(cmd);
}
assertNotNull(seen.get());
assertNull(seen.get().solrDoc.getField("signatureField"));
assertNull(seen.get().updateTerm);
}

/** a non-indexed signatureField is fine as long as overwriteDupes==false */
@Test
public void testNonIndexedSignatureField() throws Exception {
Expand Down
Loading