joshelser commented on a change in pull request #2094: URL: https://github.com/apache/hbase/pull/2094#discussion_r458952500
########## File path: hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java ########## @@ -759,12 +810,150 @@ default boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> * @param delete delete to commit if check succeeds * @param result from the CheckAndDelete * @return the possibly transformed returned value to return to client + * + * @deprecated since 3.0.0 and will be removed in 4.0.0. Use + * {@link #postCheckAndMutate(ObserverContext, CheckAndMutate, CheckAndMutateResult)} instead. */ + @Deprecated default boolean postCheckAndDelete(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, Filter filter, Delete delete, boolean result) throws IOException { return result; } + /** + * Called before checkAndMutate + * <p> + * Call CoprocessorEnvironment#bypass to skip default actions. + * If 'bypass' is set, we skip out on calling any subsequent chained coprocessors. + * <p> + * Note: Do not retain references to any Cells in actions beyond the life of this invocation. + * If need a Cell reference for later use, copy the cell and use that. + * @param c the environment provided by the region server + * @param checkAndMutate the CheckAndMutate object + * @param result the default value of the result + * @return the return value to return to client if bypassing default processing + * @throws IOException if an error occurred on the coprocessor + */ + default CheckAndMutateResult preCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c, + CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException { + if (checkAndMutate.getAction() instanceof Put) { Review comment: Every time I see this, I want to suggest you use a [visitor pattern](https://en.wikipedia.org/wiki/Visitor_pattern) to reduce the boilerplate, but that would require putting more logic on Put/Delete which not worth it. :shrug: ########## File path: hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java ########## @@ -3543,4 +3546,72 @@ public static RSGroupInfo toGroupInfo(RSGroupProtos.RSGroupInfo proto) { return RSGroupProtos.RSGroupInfo.newBuilder().setName(pojo.getName()).addAllServers(hostports) .addAllTables(tables).addAllConfiguration(configuration).build(); } + + public static CheckAndMutate toCheckAndMutate(ClientProtos.Condition condition, + MutationProto mutation, CellScanner cellScanner) throws IOException { + byte[] row = condition.getRow().toByteArray(); + CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row); + Filter filter = condition.hasFilter() ? ProtobufUtil.toFilter(condition.getFilter()) : null; + if (filter != null) { + builder.ifMatches(filter); + } else { + builder.ifMatches(condition.getFamily().toByteArray(), + condition.getQualifier().toByteArray(), + CompareOperator.valueOf(condition.getCompareType().name()), + ProtobufUtil.toComparator(condition.getComparator()).getValue()); + } + TimeRange timeRange = condition.hasTimeRange() ? + ProtobufUtil.toTimeRange(condition.getTimeRange()) : TimeRange.allTime(); + builder.timeRange(timeRange); + + try { + MutationType type = mutation.getMutateType(); + switch (type) { + case PUT: + return builder.build(ProtobufUtil.toPut(mutation, cellScanner)); + case DELETE: + return builder.build(ProtobufUtil.toDelete(mutation, cellScanner)); + default: + throw new DoNotRetryIOException("Unsupported mutate type: " + type.name()); + } + } catch (IllegalArgumentException e) { + throw new DoNotRetryIOException(e.getMessage()); + } + } + + public static CheckAndMutate toCheckAndMutate(ClientProtos.Condition condition, + List<Mutation> mutations) throws IOException { + assert mutations.size() > 0; + byte[] row = condition.getRow().toByteArray(); + CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row); + Filter filter = condition.hasFilter() ? ProtobufUtil.toFilter(condition.getFilter()) : null; + if (filter != null) { + builder.ifMatches(filter); + } else { + builder.ifMatches(condition.getFamily().toByteArray(), + condition.getQualifier().toByteArray(), + CompareOperator.valueOf(condition.getCompareType().name()), + ProtobufUtil.toComparator(condition.getComparator()).getValue()); + } + TimeRange timeRange = condition.hasTimeRange() ? + ProtobufUtil.toTimeRange(condition.getTimeRange()) : TimeRange.allTime(); + builder.timeRange(timeRange); + + try { + if (mutations.size() == 1) { + if (mutations.get(0) instanceof Put) { Review comment: nit: `Mutation m = mutations.get(0)` and then use `m` for the rest of this block. ########## File path: hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java ########## @@ -1770,6 +1772,7 @@ private long prepareRegionForBachPut(final Put[] puts, final MetricsWALSource so // checkAndMutate tests // //////////////////////////////////////////////////////////////////////////// @Test + @Deprecated Review comment: Probably don't need to mark deprecated tests in the future, but this is fine to leave, IMO. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org