Skip to content

Commit

Permalink
* Add exception mappers to convert storage failures to Iceberg REST c…
Browse files Browse the repository at this point in the history
…lient exceptions

* Add AccessCheckHandler to ObjectStorageMock for simulating access failures in tests.

Closes projectnessie#8738
  • Loading branch information
dimas-b committed Jul 6, 2024
1 parent 7da1bfd commit 321b96a
Show file tree
Hide file tree
Showing 40 changed files with 571 additions and 602 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2024 Dremio
*
* Licensed 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.projectnessie.catalog.files.api;

import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import org.projectnessie.nessie.immutables.NessieImmutable;

@NessieImmutable
public abstract class ObjectIOExceptionMapper {

protected abstract List<Analyzer> analyzers();

protected abstract Duration retryAfterThrottled();

protected abstract Duration retryAfterNetworkError();

protected abstract Duration reattemptAfterFetchError();

protected abstract Clock clock();

public static ImmutableObjectIOExceptionMapper.Builder builder() {
return ImmutableObjectIOExceptionMapper.builder();
}

public Optional<ObjectIOStatus> analyze(Throwable ex) {
for (Throwable th = ex; th != null; th = th.getCause()) {
for (Analyzer analyzer : analyzers()) {
OptionalInt statusCode = analyzer.httpStatusCode(th);
if (statusCode.isPresent()) {
return Optional.of(toStatus(statusCode.getAsInt(), th));
}
}
}

return Optional.empty();
}

private Instant retryAfter(Duration delay) {
return clock().instant().plus(delay);
}

private ObjectIOStatus toStatus(int httpStatus, Throwable th) {
switch (httpStatus) {
case 408:
case 425:
case 429:
return ObjectIOStatus.of(httpStatus, true, retryAfter(retryAfterThrottled()), th);

case 502:
case 503:
case 504:
return ObjectIOStatus.of(httpStatus, true, retryAfter(retryAfterNetworkError()), th);

default:
return ObjectIOStatus.of(httpStatus, false, retryAfter(reattemptAfterFetchError()), th);
}
}

public interface Analyzer {
OptionalInt httpStatusCode(Throwable th);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,21 @@
*/
package org.projectnessie.catalog.files.api;

import java.io.IOException;
import java.time.Instant;
import java.util.Optional;
import org.projectnessie.nessie.immutables.NessieImmutable;

public abstract class ObjectIOException extends IOException {
public ObjectIOException(Throwable cause) {
super(cause);
}
@NessieImmutable
public interface ObjectIOStatus {
int httpStatusCode();

public ObjectIOException(String message) {
super(message);
}
boolean isRetryable();

public ObjectIOException(String message, Throwable cause) {
super(message, cause);
}
Instant reattemptAfter();

public abstract boolean isRetryable();
Throwable cause();

public abstract Optional<Instant> retryNotBefore();
static ObjectIOStatus of(
int httpCode, boolean retryable, Instant reattemptAfter, Throwable cause) {
return ImmutableObjectIOStatus.of(httpCode, retryable, reattemptAfter, cause);
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 321b96a

Please sign in to comment.