-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate failure and result handler class
Signed-off-by: Chen Dai <[email protected]>
- Loading branch information
Showing
3 changed files
with
117 additions
and
60 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
72 changes: 72 additions & 0 deletions
72
...core/src/main/scala/org/opensearch/flint/core/http/handler/ExceptionClassNameHandler.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,72 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.flint.core.http.handler; | ||
|
||
import static java.util.Collections.newSetFromMap; | ||
|
||
import dev.failsafe.function.CheckedPredicate; | ||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.WeakHashMap; | ||
|
||
/** | ||
* Failure handler based on exception class type check. | ||
*/ | ||
public class ExceptionClassNameHandler implements CheckedPredicate<Throwable> { | ||
|
||
/** | ||
* Retryable exception class types. | ||
*/ | ||
private final Set<Class<? extends Throwable>> retryableExceptions; | ||
|
||
/** | ||
* @return exception class handler or empty handler (treat any exception non-retryable) | ||
*/ | ||
public static CheckedPredicate<? extends Throwable> create( | ||
Optional<String> exceptionClassNames) { | ||
// By default, Failsafe handles any Exception | ||
if (exceptionClassNames.isEmpty()) { | ||
return ex -> false; | ||
} | ||
return new ExceptionClassNameHandler(exceptionClassNames.get()); | ||
} | ||
|
||
public ExceptionClassNameHandler(String exceptionClassNames) { | ||
// Use weak collection avoids blocking class unloading | ||
this.retryableExceptions = newSetFromMap(new WeakHashMap<>()); | ||
Arrays.stream(exceptionClassNames.split(",")) | ||
.map(String::trim) | ||
.map(this::loadClass) | ||
.forEach(retryableExceptions::add); | ||
} | ||
|
||
@Override | ||
public boolean test(Throwable throwable) throws Throwable { | ||
// Consider retryable if exception found anywhere on stacktrace. | ||
// Meanwhile, handle nested exception to avoid dead loop by seen hash set. | ||
Set<Throwable> seen = new HashSet<>(); | ||
while (throwable != null && seen.add(throwable)) { | ||
for (Class<? extends Throwable> retryable : retryableExceptions) { | ||
if (retryable.isInstance(throwable)) { | ||
return true; | ||
} | ||
} | ||
throwable = throwable.getCause(); | ||
} | ||
return false; | ||
} | ||
|
||
private Class<? extends Throwable> loadClass(String className) { | ||
try { | ||
//noinspection unchecked | ||
return (Class<? extends Throwable>) Class.forName(className); | ||
} catch (ClassNotFoundException e) { | ||
throw new IllegalStateException("Failed to load class " + className, e); | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
flint-core/src/main/scala/org/opensearch/flint/core/http/handler/HttpStatusCodeHandler.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,41 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.opensearch.flint.core.http.handler; | ||
|
||
import dev.failsafe.function.CheckedPredicate; | ||
import java.util.Arrays; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import org.apache.http.HttpResponse; | ||
|
||
/** | ||
* Failure handler based on status code in HTTP response. | ||
* | ||
* @param <T> result type (supposed to be HttpResponse for OS client) | ||
*/ | ||
public class HttpStatusCodeHandler<T> implements CheckedPredicate<T> { | ||
|
||
/** | ||
* Retryable HTTP status code list | ||
*/ | ||
private final String[] httpStatusCodes; | ||
|
||
public HttpStatusCodeHandler(String httpStatusCodes) { | ||
this.httpStatusCodes = httpStatusCodes.split(","); | ||
} | ||
|
||
@Override | ||
public boolean test(T result) throws Throwable { | ||
Set<Integer> retryableStatusCodes = | ||
Arrays.stream(httpStatusCodes) | ||
.map(String::trim) | ||
.map(Integer::valueOf) | ||
.collect(Collectors.toSet()); | ||
|
||
return retryableStatusCodes.contains( | ||
((HttpResponse) result).getStatusLine().getStatusCode()); | ||
} | ||
} |