LanceIndexJobResult.java
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.datasource.lance.job;
import com.google.gson.annotations.SerializedName;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
* The immutable typed result of the one-shot invocation, persisted on the job.
* Contains only what is needed to classify the invocation: the saved typed
* code, the classified completion reason, a bounded sanitized message, and
* whether trusted pre-invocation revalidation observed relevant external
* metadata advancement. Never carries secrets, raw provider responses, or
* unbounded text.
*/
public class LanceIndexJobResult {
public static final int MAX_MESSAGE_BYTES = 1024;
@SerializedName(value = "rc")
private LanceIndexJobResultCode resultCode = LanceIndexJobResultCode.NO_TRUSTED_RESULT;
@SerializedName(value = "cr")
private LanceIndexJobCompletionReason completionReason = LanceIndexJobCompletionReason.NONE;
@SerializedName(value = "msg")
private String sanitizedMessage;
@SerializedName(value = "ema")
private boolean externalMetadataAdvanced;
/**
* No-arg constructor for Gson replay only; missing fields keep the safe
* defaults declared above.
*/
public LanceIndexJobResult() {
}
public LanceIndexJobResult(LanceIndexJobResultCode resultCode, LanceIndexJobCompletionReason completionReason,
String sanitizedMessage, boolean externalMetadataAdvanced) {
this.resultCode = Objects.requireNonNull(resultCode, "resultCode");
this.completionReason = completionReason == null ? LanceIndexJobCompletionReason.NONE : completionReason;
this.sanitizedMessage = checkMessageBytes(sanitizedMessage);
this.externalMetadataAdvanced = externalMetadataAdvanced;
}
private static String checkMessageBytes(String message) {
if (message != null && message.getBytes(StandardCharsets.UTF_8).length > MAX_MESSAGE_BYTES) {
throw new IllegalArgumentException(
"sanitized message exceeds " + MAX_MESSAGE_BYTES + " UTF-8 bytes");
}
return message;
}
public LanceIndexJobResultCode getResultCode() {
return resultCode;
}
public LanceIndexJobCompletionReason getCompletionReason() {
return completionReason;
}
public String getSanitizedMessage() {
return sanitizedMessage;
}
public boolean isExternalMetadataAdvanced() {
return externalMetadataAdvanced;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof LanceIndexJobResult)) {
return false;
}
LanceIndexJobResult that = (LanceIndexJobResult) o;
return externalMetadataAdvanced == that.externalMetadataAdvanced
&& resultCode == that.resultCode
&& completionReason == that.completionReason
&& Objects.equals(sanitizedMessage, that.sanitizedMessage);
}
@Override
public int hashCode() {
return Objects.hash(resultCode, completionReason, sanitizedMessage, externalMetadataAdvanced);
}
@Override
public String toString() {
return "LanceIndexJobResult{resultCode=" + resultCode + ", completionReason=" + completionReason
+ ", externalMetadataAdvanced=" + externalMetadataAdvanced + '}';
}
}