Skip to content

Commit 717f544

Browse files
p29876cn337131
andauthored
Gh-3238: target delete accumulo (#3249)
* Gh-3237 Implement DeleteElements for Map Store * remove unused param * spotless * wip * finish * checkstyle * codecov and sonarcloud * improve codecov and sonarcloud * reduce test duplication and add to federated store * checkstyle * remove unused properties and improve check * Gh-3238 Implement DeleteElements for Accumulo * add accumulo test to federated store * remove commented test * address comments * address comments * checkstyle * checkstyle * headers * code cov * remove public * remove AccumuloClient * code cov * checkystle * add test --------- Co-authored-by: cn337131 <141730190+cn337131@users.noreply.github.com>
1 parent cda4cdd commit 717f544

File tree

7 files changed

+493
-115
lines changed

7 files changed

+493
-115
lines changed

store-implementation/accumulo-store/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@
179179
<artifactId>junit-platform-suite</artifactId>
180180
<scope>test</scope>
181181
</dependency>
182+
<dependency>
183+
<groupId>org.mockito</groupId>
184+
<artifactId>mockito-inline</artifactId>
185+
<version>${mockito.version}</version>
186+
<scope>test</scope>
187+
</dependency>
182188
</dependencies>
183189

184190
<build>

store-implementation/accumulo-store/src/main/java/uk/gov/gchq/gaffer/accumulostore/AccumuloStore.java

+54-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.google.common.collect.Sets;
2020
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21+
2122
import org.apache.accumulo.core.client.AccumuloSecurityException;
2223
import org.apache.accumulo.core.client.BatchWriter;
2324
import org.apache.accumulo.core.client.ClientConfiguration;
@@ -42,6 +43,7 @@
4243
import uk.gov.gchq.gaffer.accumulostore.key.exception.AccumuloElementConversionException;
4344
import uk.gov.gchq.gaffer.accumulostore.key.exception.IteratorSettingException;
4445
import uk.gov.gchq.gaffer.accumulostore.operation.handler.AddElementsHandler;
46+
import uk.gov.gchq.gaffer.accumulostore.operation.handler.DeleteElementsHandler;
4547
import uk.gov.gchq.gaffer.accumulostore.operation.handler.GenerateSplitPointsFromSampleHandler;
4648
import uk.gov.gchq.gaffer.accumulostore.operation.handler.GetAdjacentIdsHandler;
4749
import uk.gov.gchq.gaffer.accumulostore.operation.handler.GetAllElementsHandler;
@@ -105,6 +107,7 @@
105107
import uk.gov.gchq.koryphe.iterable.ChainedIterable;
106108

107109
import java.nio.charset.StandardCharsets;
110+
import java.util.Arrays;
108111
import java.util.Collection;
109112
import java.util.Collections;
110113
import java.util.List;
@@ -140,6 +143,7 @@
140143
*/
141144
public class AccumuloStore extends Store {
142145

146+
private static final String MUTATION_ERROR = "Failed to create an accumulo key mutation";
143147
public static final Set<StoreTrait> TRAITS = Collections.unmodifiableSet(Sets.newHashSet(
144148
ORDERED,
145149
VISIBILITY,
@@ -415,8 +419,7 @@ protected OutputOperationHandler<GetTraits, Set<StoreTrait>> getGetTraitsHandler
415419

416420
@Override
417421
protected OperationHandler<? extends DeleteElements> getDeleteElementsHandler() {
418-
// TODO: implement accumulo delete handler logic
419-
return null;
422+
return new DeleteElementsHandler();
420423
}
421424

422425
/**
@@ -462,7 +465,7 @@ protected void insertGraphElements(final Iterable<? extends Element> elements) t
462465
try {
463466
writer.addMutation(m);
464467
} catch (final MutationsRejectedException e) {
465-
LOGGER.error("Failed to create an accumulo key mutation");
468+
LOGGER.error(MUTATION_ERROR);
466469
continue;
467470
}
468471
// If the GraphElement is a Vertex then there will only be 1 key,
@@ -478,7 +481,7 @@ protected void insertGraphElements(final Iterable<? extends Element> elements) t
478481
try {
479482
writer.addMutation(m2);
480483
} catch (final MutationsRejectedException e) {
481-
LOGGER.error("Failed to create an accumulo key mutation");
484+
LOGGER.error(MUTATION_ERROR);
482485
}
483486
}
484487
}
@@ -492,6 +495,53 @@ protected void insertGraphElements(final Iterable<? extends Element> elements) t
492495
}
493496
}
494497

498+
/**
499+
* Method to delete {@link Element}s from Accumulo.
500+
*
501+
* @param elements The elements to be deleted.
502+
* @throws StoreException If there is a failure to delete elements.
503+
*/
504+
public void deleteElements(final Iterable<? extends Element> elements) throws StoreException {
505+
deleteGraphElements(elements);
506+
}
507+
508+
protected void deleteGraphElements(final Iterable<? extends Element> elements) throws StoreException {
509+
// Create BatchWriter
510+
// Loop through elements, convert to mutations, and add to BatchWriter
511+
// The BatchWriter takes care of batching them up, sending them without
512+
// too high a latency, etc.
513+
if (elements == null) {
514+
throw new GafferRuntimeException("Could not find any elements to delete from graph.", Status.BAD_REQUEST);
515+
}
516+
517+
try (BatchWriter writer = TableUtils.createBatchWriter(this)) {
518+
for (final Element element : elements) {
519+
final Pair<Key, Key> keys;
520+
try {
521+
keys = getKeyPackage().getKeyConverter().getKeysFromElement(element);
522+
} catch (final AccumuloElementConversionException e) {
523+
LOGGER.error(FAILED_TO_CREATE_AN_ACCUMULO_FROM_ELEMENT_OF_TYPE_WHEN_TRYING_TO_INSERT_ELEMENTS, "key", element.getGroup());
524+
continue;
525+
}
526+
527+
for (final Key key : Arrays.asList(keys.getFirst(), keys.getSecond())) {
528+
if (nonNull(key)) {
529+
final Mutation m = new Mutation(key.getRow());
530+
m.putDelete(key.getColumnFamily(), key.getColumnQualifier(), key.getTimestamp());
531+
532+
try {
533+
writer.addMutation(m);
534+
} catch (final MutationsRejectedException e) {
535+
LOGGER.error(MUTATION_ERROR);
536+
}
537+
}
538+
}
539+
}
540+
} catch (final MutationsRejectedException e) {
541+
LOGGER.warn("Accumulo batch writer failed to close", e);
542+
}
543+
}
544+
495545
/**
496546
* Gets the {@link uk.gov.gchq.gaffer.accumulostore.key.AccumuloKeyPackage} in use by
497547
* this AccumuloStore.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2024 Crown Copyright
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package uk.gov.gchq.gaffer.accumulostore.operation.handler;
18+
19+
import uk.gov.gchq.gaffer.accumulostore.AccumuloStore;
20+
import uk.gov.gchq.gaffer.data.element.Element;
21+
import uk.gov.gchq.gaffer.operation.OperationException;
22+
import uk.gov.gchq.gaffer.operation.impl.delete.DeleteElements;
23+
import uk.gov.gchq.gaffer.store.Context;
24+
import uk.gov.gchq.gaffer.store.Store;
25+
import uk.gov.gchq.gaffer.store.StoreException;
26+
import uk.gov.gchq.gaffer.store.ValidatedElements;
27+
import uk.gov.gchq.gaffer.store.operation.handler.OperationHandler;
28+
29+
public class DeleteElementsHandler implements OperationHandler<DeleteElements> {
30+
31+
@Override
32+
public Object doOperation(final DeleteElements operation,
33+
final Context context, final Store store)
34+
throws OperationException {
35+
deleteElements(operation, (AccumuloStore) store);
36+
return null;
37+
}
38+
39+
private void deleteElements(final DeleteElements operation, final AccumuloStore store)
40+
throws OperationException {
41+
try {
42+
final Iterable<? extends Element> validatedElements;
43+
if (operation.isValidate()) {
44+
validatedElements = new ValidatedElements(operation.getInput(), store.getSchema(),
45+
operation.isSkipInvalidElements());
46+
} else {
47+
validatedElements = operation.getInput();
48+
}
49+
store.deleteElements(validatedElements);
50+
} catch (final StoreException e) {
51+
throw new OperationException("Failed to delete elements", e);
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)