forked from raystack/firehose
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Retryable Configuration for GRPC Sink (using CEL) (#44)
Add new config to enable response based retry in gRPC Sink Config Example Parameter: SINK_GRPC_RESPONSE_RETRY_CEL_EXPRESSION ="GenericResponse.success == false && GenericResponse.errors.exists(e, e.code == "400")" Reason for the PR: EGLC users who want to migrate expect this feature to be supported in Firehose Notes : CEL Expression: https://cel.dev/ cel-java: https://github.com/google/cel-java * [feat] Add CEL evaluator and add it to grpc sink * Remove blank check * remove unintended change * [feat] add success field checking * [feat] add evaluator method * [feat] handle descriptor update * Add test for evaluator * Update test * Update SINK_GRPC_RESPONSE_RETRY_CEL_EXPRESSION default value * Add test for GrpcSink * Rename descriptor to payloadDescriptor * Checkstyle update * Refactor instantiation logic to separate method * Remove schema refresh * Remove projectnessie and use implementation from cel-java * update checkstyle * Add comment * Update docs * Move the evaluator instantiation to factory method * Remove unused sink config * Add more testcases * revert protoc version * Add more test cases * Add more comprehensive documentation * Rename default class and update docs * Refactor typical cel functionality to util class * Add checking for expression result * Use built in UnsupportedOperationException * Update build-info-extractor * Update to classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4.33.1") * Remove OperationNotSupportedException.java * Remove jfrog build info on dependencies * - Tidy up tests - Make exception message more verbose * Bump version * Makes error type for retryable error configurable through env * Add 1 more test case * Update default value * Use default value of true on CEL Expression config to retry on default case. Remove implementation of DefaultGrpcResponsePayloadEvaluator.java
- Loading branch information
1 parent
a368c89
commit ba3220e
Showing
10 changed files
with
418 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/java/com/gotocompany/firehose/config/converter/GrpcSinkRetryErrorTypeConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.gotocompany.firehose.config.converter; | ||
|
||
import com.gotocompany.depot.error.ErrorType; | ||
import org.aeonbits.owner.Converter; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Locale; | ||
|
||
public class GrpcSinkRetryErrorTypeConverter implements Converter<ErrorType> { | ||
@Override | ||
public ErrorType convert(Method method, String s) { | ||
return ErrorType.valueOf(s.trim().toUpperCase(Locale.ROOT)); | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
src/main/java/com/gotocompany/firehose/evaluator/GrpcResponseCelPayloadEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.gotocompany.firehose.evaluator; | ||
|
||
import com.google.protobuf.Descriptors; | ||
import com.google.protobuf.Message; | ||
import com.gotocompany.firehose.utils.CelUtils; | ||
import dev.cel.common.types.CelKind; | ||
import dev.cel.compiler.CelCompiler; | ||
import dev.cel.runtime.CelRuntime; | ||
import dev.cel.runtime.CelRuntimeFactory; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
/** | ||
* Implementation of PayloadEvaluator that evaluates gRPC responses using CEL (Common Expression Language). | ||
*/ | ||
@Slf4j | ||
public class GrpcResponseCelPayloadEvaluator implements PayloadEvaluator<Message> { | ||
|
||
private final Descriptors.Descriptor descriptor; | ||
private CelRuntime.Program celProgram; | ||
|
||
/** | ||
* Constructs a GrpcResponseCelPayloadEvaluator with the specified descriptor and CEL expression. | ||
* | ||
* @param descriptor the descriptor of the gRPC message | ||
* @param celExpression the CEL expression to evaluate against the message | ||
*/ | ||
public GrpcResponseCelPayloadEvaluator(Descriptors.Descriptor descriptor, String celExpression) { | ||
this.descriptor = descriptor; | ||
buildCelEnvironment(celExpression); | ||
} | ||
|
||
/** | ||
* Evaluates the given gRPC message payload using the CEL program. | ||
* | ||
* @param payload the gRPC message to be evaluated | ||
* @return true if the payload passes the evaluation, false otherwise | ||
*/ | ||
@Override | ||
public boolean evaluate(Message payload) { | ||
if (!descriptor.getFullName().equals(payload.getDescriptorForType().getFullName())) { | ||
throw new IllegalArgumentException(String.format("Payload %s does not match descriptor %s", | ||
payload.getDescriptorForType().getFullName(), descriptor.getFullName())); | ||
} | ||
return (boolean) CelUtils.evaluate(this.celProgram, payload); | ||
} | ||
|
||
/** | ||
* Builds the CEL environment required to evaluate the CEL expression. | ||
* | ||
* @param celExpression the CEL expression to evaluate against the message | ||
* @throws IllegalArgumentException if the CEL expression is invalid or if the evaluator cannot be constructed | ||
*/ | ||
private void buildCelEnvironment(String celExpression) { | ||
CelCompiler celCompiler = CelUtils.initializeCelCompiler(this.descriptor); | ||
CelRuntime celRuntime = CelRuntimeFactory.standardCelRuntimeBuilder() | ||
.build(); | ||
this.celProgram = CelUtils.initializeCelProgram(celExpression, celRuntime, celCompiler, | ||
celType -> celType.kind().equals(CelKind.BOOL)); | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/gotocompany/firehose/evaluator/PayloadEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.gotocompany.firehose.evaluator; | ||
|
||
/** | ||
* A generic interface for evaluating payloads. | ||
* | ||
* @param <T> the type of payload to be evaluated | ||
*/ | ||
public interface PayloadEvaluator<T> { | ||
/** | ||
* Evaluates the given payload. | ||
* | ||
* @param payload the payload to be evaluated | ||
* @return true if the payload passes the evaluation, false otherwise | ||
*/ | ||
boolean evaluate(T payload); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
src/test/java/com/gotocompany/firehose/converter/GrpcSinkRetryErrorTypeConverterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.gotocompany.firehose.converter; | ||
|
||
import com.gotocompany.depot.error.ErrorType; | ||
import com.gotocompany.firehose.config.converter.GrpcSinkRetryErrorTypeConverter; | ||
import org.junit.Test; | ||
import org.junit.jupiter.api.Assertions; | ||
|
||
import java.util.Arrays; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
|
||
public class GrpcSinkRetryErrorTypeConverterTest { | ||
@Test | ||
public void shouldConvertToAppropriateEnumType() { | ||
Map<String, ErrorType> stringToExpectedValue = Arrays.stream(ErrorType.values()) | ||
.collect(Collectors.toMap(ErrorType::toString, Function.identity())); | ||
GrpcSinkRetryErrorTypeConverter grpcSinkRetryErrorTypeConverter = new GrpcSinkRetryErrorTypeConverter(); | ||
|
||
stringToExpectedValue.keySet().stream() | ||
.forEach(key -> { | ||
ErrorType expectedValue = stringToExpectedValue.get(key); | ||
ErrorType actualValue = grpcSinkRetryErrorTypeConverter.convert(null, key); | ||
Assertions.assertEquals(expectedValue, actualValue); | ||
}); | ||
} | ||
|
||
@Test(expected = IllegalArgumentException.class) | ||
public void shouldThrowExceptionForInvalidValue() { | ||
GrpcSinkRetryErrorTypeConverter grpcSinkRetryErrorTypeConverter = new GrpcSinkRetryErrorTypeConverter(); | ||
grpcSinkRetryErrorTypeConverter.convert(null, "ErrorType.UNREGISTERED"); | ||
} | ||
} |
Oops, something went wrong.