Class FailedMutation

java.lang.Object
io.github.flink.gcp.connector.bigtable.sink.FailedMutation
All Implemented Interfaces:
FailedElement

@Public public final class FailedMutation extends Object implements FailedElement
A single row mutation that terminally failed to be written to Bigtable, as passed to a FailureHandler<FailedMutation>.

Carries the RowMutationEntry the serializer produced rather than the original record: the sink writer is stateless and retains only mutations, so by the time the service rejects one the original record object no longer exists. When serialization itself failed, getEntry() and getRowKey() are null.

getPayloadBytes() is the serialized MutateRowsRequest.Entry — the row key and every mutation of it — so a dead-letter consumer recovers the whole mutation with MutateRowsRequest.Entry.parseFrom(bytes).

Instances are created by the sink and are not serializable.

  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the table as project.instance.table.
    Returns the underlying failure, or null when none is available.
    Returns the connector that produced the failure, as a lower-case identifier ( "bigquery", "bigtable", "cloudtasks", "pubsub", "spanner") — stable, so dead-letter consumers can key on it.
    Returns the table the mutation was routed to.
    com.google.cloud.bigtable.data.v2.models.RowMutationEntry
    Returns the mutation the serializer produced, or null when the record could not be serialized in the first place.
    Returns the failure description.
    com.google.protobuf.ByteString
    Returns the serialized mutation — row key and every mutation of it — or null when serialization itself failed.
    com.google.protobuf.ByteString
    Returns the row key the mutation applies to, or null when the record could not be serialized.
    of(TableDestination destination, com.google.cloud.bigtable.data.v2.models.RowMutationEntry entry, String errorMessage, Throwable cause)
    Creates a failed mutation.
    Renders the failure as its siblings do: the destination, the size of the failed payload, and the message.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Method Details

    • of

      public static FailedMutation of(TableDestination destination, @Nullable com.google.cloud.bigtable.data.v2.models.RowMutationEntry entry, String errorMessage, @Nullable Throwable cause)
      Creates a failed mutation. Intended for the sink implementation (and tests of custom handlers).
      Parameters:
      destination - the table the mutation was routed to
      entry - the mutation, or null when serialization itself failed
      errorMessage - the failure description
      cause - the underlying failure, or null
      Returns:
      the failed mutation
    • getDestination

      public TableDestination getDestination()
      Returns the table the mutation was routed to.
    • getEntry

      @Nullable public com.google.cloud.bigtable.data.v2.models.RowMutationEntry getEntry()
      Returns the mutation the serializer produced, or null when the record could not be serialized in the first place.
    • getRowKey

      @Nullable public com.google.protobuf.ByteString getRowKey()
      Returns the row key the mutation applies to, or null when the record could not be serialized.
    • getConnector

      public String getConnector()
      Description copied from interface: FailedElement
      Returns the connector that produced the failure, as a lower-case identifier ( "bigquery", "bigtable", "cloudtasks", "pubsub", "spanner") — stable, so dead-letter consumers can key on it.
      Specified by:
      getConnector in interface FailedElement
    • describeDestination

      public String describeDestination()
      Returns the table as project.instance.table.
      Specified by:
      describeDestination in interface FailedElement
    • getPayloadBytes

      @Nullable public com.google.protobuf.ByteString getPayloadBytes()
      Returns the serialized mutation — row key and every mutation of it — or null when serialization itself failed.
      Specified by:
      getPayloadBytes in interface FailedElement
    • getErrorMessage

      public String getErrorMessage()
      Description copied from interface: FailedElement
      Returns the failure description. It is always present, even when FailedElement.getCause() is null, and it is the detail that FailureHandler.failJob() raises and FailureHandler.logAndDrop() logs.
      Specified by:
      getErrorMessage in interface FailedElement
    • getCause

      @Nullable public Throwable getCause()
      Description copied from interface: FailedElement
      Returns the underlying failure, or null when none is available.
      Specified by:
      getCause in interface FailedElement
    • toString

      public String toString()
      Renders the failure as its siblings do: the destination, the size of the failed payload, and the message.

      It used to render the row key with toStringUtf8(), which was the worst of both. A row key is arbitrary bytes, so decoding invalid UTF-8 substituted U+FFFD rather than failing — 0xFE and 0xFF both arrived as one replacement character — while a key that was valid UTF-8 went into the line exactly. It neither identified the row nor kept it out of a log.

      What replaces it is the shape FailedTask, FailedRow and FailedMessage share, and it is the whole payload each of them measures rather than one field of it: the mutation's size is what an operator asks after an INVALID_ARGUMENT on a batch, and a row key's length answers that only for the part of it the key happens to be. Spanner's FailedMutation carries no key either.

      Not printing the key is deliberate and is not the rule an exception message follows. A message has one chance to name the offending row and no accessors, which is why the table layer's decode-failure guards and its empty-mutation refusal do carry an escaped key — a payload format's own failure carries whatever that format wrote. This type is handed to a FailureHandler a user writes, and has getRowKey() for a handler that wants the row.

      This bounds the rendering and not the object. When serialization itself failed, getRowKey() is null — there is no entry to read it from — so getCause() is the only place the row can be named. Whether it is named is that message's business and not this type's: the table sink's empty-mutation refusal carries the row key escaped, since a message is the one place that must name it, so a handler logging that cause publishes it — while its other refusals name none, and a cause here is just as likely to be whatever a user's own BigtableSerializationSchema threw. So this is neither a hole to close here nor a guarantee to lean on.

      Overrides:
      toString in class Object