package org.gbif.occurrence.deleter;
import org.gbif.api.model.occurrence.Occurrence;
import org.gbif.api.model.occurrence.VerbatimOccurrence;
import org.gbif.dwc.terms.DwcTerm;
import org.gbif.occurrence.common.identifier.HolyTriplet;
import org.gbif.occurrence.common.identifier.PublisherProvidedUniqueIdentifier;
import org.gbif.occurrence.common.identifier.UniqueIdentifier;
import org.gbif.occurrence.persistence.api.OccurrenceKeyPersistenceService;
import org.gbif.occurrence.persistence.api.OccurrencePersistenceService;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Meter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A simple service that can handle the deletion of a single occurrence (including its secondary index entry).
*/
public class OccurrenceDeletionService {
private static final Logger LOG = LoggerFactory.getLogger(OccurrenceDeletionService.class);
private final OccurrencePersistenceService occurrenceService;
private final OccurrenceKeyPersistenceService occurrenceKeyService;
private final Meter occurrencesDeleted =
Metrics.newMeter(OccurrenceDeletionService.class, "deletes", "deletes", TimeUnit.SECONDS);
public OccurrenceDeletionService(OccurrencePersistenceService occurrenceService,
OccurrenceKeyPersistenceService occurrenceKeyService) {
this.occurrenceService = checkNotNull(occurrenceService, "occurrenceService can't be null");
this.occurrenceKeyService = checkNotNull(occurrenceKeyService, "occurrenceKeyService can't be null");
}
public Occurrence deleteOccurrence(int occurrenceKey) {
checkArgument(occurrenceKey > 0, "occurrenceKey must be > 0");
LOG.debug("Deleting occurrence for key [{}]", occurrenceKey);
// TODO: include dwcOccurrenceId lookup deletion (requires occ id on verbatim object)
VerbatimOccurrence verbatim = occurrenceService.getVerbatim(occurrenceKey);
if (verbatim == null) {
LOG.info("No occurrence for key [{}], ignoring deletion request", occurrenceKey);
return null;
}
Set<UniqueIdentifier> lookupsToDelete = Sets.newHashSet();
// add the 'holy triplet' if any exist
try {
if (verbatim.getDatasetKey() != null) {
final String instCode = verbatim.getVerbatimField(DwcTerm.institutionCode);
final String collCode = verbatim.getVerbatimField(DwcTerm.collectionCode);
final String catNum= verbatim.getVerbatimField(DwcTerm.catalogNumber);
//TODO: retrieve it from somewhere via the persistence layer!
final String unitQualifier = null;
lookupsToDelete.add(new HolyTriplet(verbatim.getDatasetKey(), instCode, collCode, catNum, unitQualifier));
}
} catch (IllegalArgumentException e) {
LOG.debug("No valid triplet for occurrenceKey [{}]", occurrenceKey, e);
}
// add the occurrenceID if it exists
String occurrenceID = verbatim.getVerbatimField(DwcTerm.occurrenceID);
if (!Strings.isNullOrEmpty(occurrenceID)) {
lookupsToDelete.add(new PublisherProvidedUniqueIdentifier(verbatim.getDatasetKey(), occurrenceID));
}
if (lookupsToDelete.isEmpty()) {
LOG.info("No triplet or occurrenceID found for occurrence [{}] therefore can't delete lookups", occurrenceKey);
} else {
occurrenceKeyService.deleteKeyByUniqueIdentifiers(lookupsToDelete);
}
// return the deleted occurrence
Occurrence deleted = occurrenceService.delete(occurrenceKey);
if (deleted != null) {
occurrencesDeleted.mark();
}
return deleted;
}
}