Skip to content
This repository has been archived by the owner on Jun 1, 2021. It is now read-only.

Commit

Permalink
#54: Added extra logging to atomic update in order to bring more ligh…
Browse files Browse the repository at this point in the history
…t to the issue.
  • Loading branch information
alfonso_noriega committed Aug 16, 2018
1 parent 5161e08 commit df6ea95
Showing 1 changed file with 52 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -619,35 +619,10 @@ public boolean execute(Update update,DocumentFactory factory) {
final boolean isUpdatable = factory.isUpdatable() && factory.getFields().values().stream()
.allMatch( descriptor -> descriptor.isUpdate());
if (isUpdatable) {
final SolrInputDocument sdoc = new SolrInputDocument();
sdoc.addField(ID, update.getId());
sdoc.addField(TYPE, factory.getType());

HashMap<FieldDescriptor<?>, HashMap<String, SortedSet<UpdateOperation>>> updateOptions = update.getOptions();
updateOptions.keySet()
.forEach(fieldDescriptor ->
Stream.of(UseCase.values()).forEach(useCase ->
updateOptions.get(fieldDescriptor).keySet()
.stream().forEach(context -> {
//NOTE: Backwards compatibility
final String updateContext = Objects.isNull(context)? update.getUpdateContext() : context;
final String fieldName = getFieldname(fieldDescriptor, useCase, updateContext);
if (fieldName != null) {
final Map<String, Object> fieldModifiers = new HashMap<>();
updateOptions.get(fieldDescriptor).get(context).stream().forEach(entry -> {
UpdateOperations opType = entry.getType();
if(fieldName.startsWith("dynamic_single_") && useCase.equals(UseCase.Sort) && opType.equals(UpdateOperations.add)) {
opType = set;
}
fieldModifiers.put(opType.name(),
toSolrJType(SolrUtils.FieldValue.getFieldCaseValue(entry.getValue(), fieldDescriptor, useCase)));

});
sdoc.addField(fieldName, fieldModifiers);
}
})
)
);
//Creates an atomic update solr document
final SolrInputDocument sdoc = getSolrUpdateDocument(update, factory.getType());

try {

if (solrClientLogger.isTraceEnabled()) {
Expand All @@ -659,27 +634,29 @@ public boolean execute(Update update,DocumentFactory factory) {
SolrInputDocument finalDoc = sdoc;

//Get the original document
log.debug("Atomic Update - Get version of original document [{}].",update.getId());
final SolrDocument updatedDoc = solrClient.getById(update.getId());

//Setting the document version for optimistic concurrency
final Object version = updatedDoc.getFieldValue("_version_");
if (Objects.nonNull(version)) {
finalDoc.setField("_version_", version);
} else {
log.warn("Error updating document '{}': " +
log.warn("Error updating document [{}]: " +
"Atomic updates in nested documents are not supported by Solr", updatedDoc.get(ID));

return false;
}

//Get the nested docs of the document if existing
log.debug("Atomic Update - Get nested documents of [{}].",update.getId());
final NamedList<Object> paramList = new NamedList<>();
paramList.add(CommonParams.Q, "!( _id_:"+ update.getId()+")&(_root_:"+ update.getId()+")");
final QueryResponse query = solrClient.query(SolrParams.toSolrParams(paramList), SolrRequest.METHOD.POST);

//if the document has nested docs solr does not support atomic updates
if (CollectionUtils.isNotEmpty(query.getResults())) {
log.info("Update document `{}`: doc has {} nested documents, changing from partial update to full index.",
log.debug("Update document [{}]: doc has {} nested documents, changing from partial update to full index.",
finalDoc.getFieldValue(SolrUtils.Fieldname.ID), query.getResults().size());
//Get the list of nested documents
final List<SolrInputDocument> childDocs = query.getResults().stream()
Expand All @@ -690,11 +667,12 @@ public boolean execute(Update update,DocumentFactory factory) {
}

try {
log.info("Updating document `{}`: current version `{}`", finalDoc.getFieldValue(SolrUtils.Fieldname.ID), version);
solrClient.add(finalDoc);
log.debug("Atomic Update - Updating document [{}]: current version [{}]", finalDoc.getFieldValue(SolrUtils.Fieldname.ID), version);
final UpdateResponse response = solrClient.add(finalDoc);
log.debug("Atomic Update - Solr update time: query time [{}] - elapsed time [{}]", response.getQTime(), response.getQTime());
return true;
} catch (HttpSolrClient.RemoteSolrException e) {
log.warn("Error updating document {}: {}", finalDoc.getFieldValue(ID),e.getMessage(), e);
log.warn("Error updating document [{}]: [{}]", finalDoc.getFieldValue(ID),e.getMessage(), e);
return false;
}

Expand All @@ -709,12 +687,53 @@ public boolean execute(Update update,DocumentFactory factory) {
}
}

private SolrInputDocument getSolrUpdateDocument(Update update, String type) {

final SolrInputDocument sdoc = new SolrInputDocument();
sdoc.addField(ID, update.getId());
sdoc.addField(TYPE, type);

log.debug("Atomic Update - Mapping the Vind update operations to a solr document with ID [{}].", update.getId());
final HashMap<FieldDescriptor<?>, HashMap<String, SortedSet<UpdateOperation>>> updateOptions = update.getOptions();

log.debug("Atomic Update - Updating {} fields.", updateOptions.keySet().size());
updateOptions.keySet()
.forEach(fieldDescriptor -> {
log.debug("Atomic Update - Updating {} different contexts for field [{}].", updateOptions.get(fieldDescriptor).keySet().size(), fieldDescriptor);
updateOptions.get(fieldDescriptor).keySet()
.stream().forEach(context ->
Stream.of(UseCase.values()).forEach(useCase -> {
//NOTE: Backwards compatibility
final String updateContext = Objects.isNull(context)? update.getUpdateContext() : context;
final String fieldName = getFieldname(fieldDescriptor, useCase, updateContext);
if (fieldName != null) {
final Map<String, Object> fieldModifiers = new HashMap<>();
updateOptions.get(fieldDescriptor).get(context).stream().forEach(entry -> {
UpdateOperations opType = entry.getType();
if(fieldName.startsWith("dynamic_single_") && useCase.equals(UseCase.Sort) && opType.equals(UpdateOperations.add)) {
opType = set;
}
fieldModifiers.put(opType.name(),
toSolrJType(SolrUtils.FieldValue.getFieldCaseValue(entry.getValue(), fieldDescriptor, useCase)));

});
sdoc.addField(fieldName, fieldModifiers);
}
})
);
}
);
return sdoc;
}

private SolrInputDocument getUpdatedSolrDocument(SolrInputDocument sdoc, SolrDocument updatedDoc, List<SolrInputDocument> nestedDocs) {

//TODO:find a better way - non deprecated way
//Create an input document from the original doc to be updated
final SolrInputDocument inputDoc = ClientUtils.toSolrInputDocument(updatedDoc);

log.debug("Atomic Update - Manually update Document [{}].", sdoc.getField(ID).getValue());

//Add nested documents to the doc
inputDoc.addChildDocuments(nestedDocs);

Expand Down

0 comments on commit df6ea95

Please sign in to comment.