下面列出了org.springframework.boot.web.server.WebServerException#com.linecorp.armeria.common.util.Exceptions 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private HttpResponse serveInternalRepo(ServiceRequestContext ctx, HttpRequest req,
MetadataService mds, User user,
String projectName) throws Exception {
if (user.isAdmin()) {
return unwrap().serve(ctx, req);
}
// We do not manage permission for the internal repository. Actually we do not have a metadata of that.
// So we need to check whether the current user is an 'administrator' or not when the request is
// accessing to the internal repository.
return HttpResponse.from(mds.findRole(projectName, user).handle((role, cause) -> {
if (cause != null) {
return handleException(ctx, cause);
}
if (!user.isAdmin()) {
return HttpApiUtil.throwResponse(
ctx, HttpStatus.FORBIDDEN,
"Repository '%s/%s' can be accessed only by an administrator.",
projectName, Project.REPO_DOGMA);
}
try {
return unwrap().serve(ctx, req);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
}));
}
@Override
protected CompletionStage<Void> doStart(@Nullable Void unused) throws Exception {
return execute("startup", () -> {
try {
CentralDogma.this.doStart();
if (pluginsForAllReplicas != null) {
final ProjectManager pm = CentralDogma.this.pm;
final CommandExecutor executor = CentralDogma.this.executor;
final MeterRegistry meterRegistry = CentralDogma.this.meterRegistry;
if (pm != null && executor != null && meterRegistry != null) {
pluginsForAllReplicas.start(cfg, pm, executor, meterRegistry, purgeWorker).join();
}
}
} catch (Exception e) {
Exceptions.throwUnsafely(e);
}
});
}
@Override
public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) {
// if (ctx.additionalRequestHeaders().contains(header) || req.headers().contains(header)) {
// return delegate().execute(ctx, req);
// }
return HttpResponse.from(
(type == TokenType.ACCESS_TOKEN
? accessTokenProvider.getAccessToken()
: accessTokenProvider.getGoogleIdToken())
.thenApplyAsync(
(token) -> {
ctx.addAdditionalRequestHeader(header, "Bearer " + token);
try {
return delegate().execute(ctx, req);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
},
ctx.contextAwareEventLoop()));
}
@Override
public void start() throws Exception {
logger.trace("Getting Armeria Server Builder");
final ServerBuilder sb = ((ArmeriaServerFactory) serverFactory).getServerBuilder();
logger.trace("Calling Server Configurator");
serverConfigurator.configure(sb);
server = sb.build();
if (logger.isDebugEnabled()) {
logger.debug("Built server {}", server);
}
logger.info("Starting Armeria Server");
try {
server.start().join();
} catch (Throwable cause) {
Exceptions.throwUnsafely(Exceptions.peel(cause));
}
logger.info("Started Armeria Server");
}
@Test
void maxInboundSize_tooBig() throws Exception {
final StreamingOutputCallRequest request =
StreamingOutputCallRequest.newBuilder()
.addResponseParameters(ResponseParameters.newBuilder().setSize(1))
.build();
final int size = blockingStub.streamingOutputCall(request).next().getSerializedSize();
requestLogQueue.take();
final TestServiceBlockingStub stub =
Clients.newDerivedClient(
blockingStub,
GrpcClientOptions.MAX_INBOUND_MESSAGE_SIZE_BYTES.newValue(size - 1));
final Throwable t = catchThrowable(() -> stub.streamingOutputCall(request).next());
assertThat(t).isInstanceOf(StatusRuntimeException.class);
assertThat(((StatusRuntimeException) t).getStatus().getCode()).isEqualTo(Code.RESOURCE_EXHAUSTED);
assertThat(Exceptions.traceText(t)).contains("exceeds maximum");
checkRequestLog((rpcReq, rpcRes, grpcStatus) -> {
assertThat(rpcReq.params()).containsExactly(request);
assertThat(grpcStatus).isNotNull();
assertThat(grpcStatus.getCode()).isEqualTo(Code.RESOURCE_EXHAUSTED);
});
}
@Test
void maxOutboundSize_tooBig() throws Exception {
// set at least one field to ensure the size is non-zero.
final StreamingOutputCallRequest request =
StreamingOutputCallRequest.newBuilder()
.addResponseParameters(ResponseParameters.newBuilder().setSize(1))
.build();
final TestServiceBlockingStub stub =
Clients.newDerivedClient(
blockingStub,
GrpcClientOptions.MAX_OUTBOUND_MESSAGE_SIZE_BYTES.newValue(
request.getSerializedSize() - 1));
final Throwable t = catchThrowable(() -> stub.streamingOutputCall(request).next());
assertThat(t).isInstanceOf(StatusRuntimeException.class);
assertThat(((StatusRuntimeException) t).getStatus().getCode()).isEqualTo(Code.CANCELLED);
assertThat(Exceptions.traceText(t)).contains("message too large");
checkRequestLog((rpcReq, rpcRes, grpcStatus) -> {
assertThat(rpcReq.params()).containsExactly(request);
assertThat(grpcStatus).isNotNull();
assertThat(grpcStatus.getCode()).isEqualTo(Code.CANCELLED);
});
}
@ParameterizedTest
@ArgumentsSource(SerializationFormatProvider.class)
void testSync_FileService_create_exception(SerializationFormat defaultSerializationFormat)
throws Exception {
final FileService.Client client = new FileService.Client.Factory().getClient(
inProto(defaultSerializationFormat), outProto(defaultSerializationFormat));
client.send_create(BAZ);
assertThat(out.length()).isGreaterThan(0);
final RuntimeException exception = Exceptions.clearTrace(new RuntimeException());
final THttpService service = THttpService.of((FileService.Iface) path -> {
throw exception;
}, defaultSerializationFormat);
invoke(service);
try {
client.recv_create();
fail(TApplicationException.class.getSimpleName() + " not raised.");
} catch (TApplicationException e) {
assertThat(e.getType()).isEqualTo(TApplicationException.INTERNAL_ERROR);
assertThat(e.getMessage()).contains(exception.toString());
}
}
@ParameterizedTest
@ArgumentsSource(SerializationFormatProvider.class)
void testAsync_FileService_create_exception(SerializationFormat defaultSerializationFormat)
throws Exception {
final FileService.Client client = new FileService.Client.Factory().getClient(
inProto(defaultSerializationFormat), outProto(defaultSerializationFormat));
client.send_create(BAZ);
assertThat(out.length()).isGreaterThan(0);
final RuntimeException exception = Exceptions.clearTrace(new RuntimeException());
final THttpService service = THttpService.of(
(FileService.AsyncIface) (path, resultHandler) ->
resultHandler.onError(exception), defaultSerializationFormat);
invoke(service);
try {
client.recv_create();
fail(TApplicationException.class.getSimpleName() + " not raised.");
} catch (TApplicationException e) {
assertThat(e.getType()).isEqualTo(TApplicationException.INTERNAL_ERROR);
assertThat(e.getMessage()).contains(exception.toString());
}
}
@ParameterizedTest
@ArgumentsSource(SerializationFormatProvider.class)
void testIdentity_FileService_create_exception(SerializationFormat defaultSerializationFormat)
throws Exception {
final FileService.Client client = new FileService.Client.Factory().getClient(
inProto(defaultSerializationFormat), outProto(defaultSerializationFormat));
client.send_create(BAZ);
assertThat(out.length()).isGreaterThan(0);
final RuntimeException exception = Exceptions.clearTrace(new RuntimeException());
final THttpService syncService = THttpService.of((FileService.Iface) path -> {
throw exception;
}, defaultSerializationFormat);
final THttpService asyncService = THttpService.of(
(FileService.AsyncIface) (path, resultHandler) ->
resultHandler.onError(exception), defaultSerializationFormat);
invokeTwice(syncService, asyncService);
assertThat(promise.get()).isEqualTo(promise2.get());
}
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.https(new InetSocketAddress("127.0.0.1", 0));
sb.tls(ssc.certificateFile(), ssc.privateKeyFile());
sb.tlsCustomizer(ssl -> {
try {
ssl.trustManager(TestUtils.loadCert("ca.pem"));
} catch (IOException e) {
Exceptions.throwUnsafely(e);
}
});
sb.maxRequestLength(16 * 1024 * 1024);
sb.serviceUnder("/", grpcService.decorate((delegate, ctx, req) -> {
ctxCapture.set(ctx);
return delegate.serve(ctx, req);
}));
}
private void failAndReset(Throwable cause) {
if (cause instanceof ProxyConnectException) {
// ProxyConnectException is handled by HttpSessionHandler.exceptionCaught().
return;
}
fail(cause);
final Http2Error error;
if (Exceptions.isStreamCancelling(cause)) {
error = Http2Error.CANCEL;
} else {
error = Http2Error.INTERNAL_ERROR;
}
if (error.code() != Http2Error.CANCEL.code()) {
Exceptions.logIfUnexpected(logger, ch,
HttpSession.get(ch).protocol(),
"a request publisher raised an exception", cause);
}
if (ch.isActive()) {
encoder.writeReset(id, streamId(), error);
ch.flush();
}
}
@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
return HttpResponse.from(AuthorizerUtil.authorize(authorizer, ctx, req).handleAsync((result, cause) -> {
try {
final HttpService delegate = (HttpService) unwrap();
if (cause == null) {
if (result != null) {
return result ? successHandler.authSucceeded(delegate, ctx, req)
: failureHandler.authFailed(delegate, ctx, req, null);
}
cause = AuthorizerUtil.newNullResultException(authorizer);
}
return failureHandler.authFailed(delegate, ctx, req, cause);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
}, ctx.contextAwareEventLoop()));
}
@Override
public HttpService asService() {
final HttpFile delegate = this.delegate;
if (delegate != null) {
return delegate.asService();
}
return (ctx, req) -> HttpResponse.from(stage.thenApply(file -> {
setDelegate(file);
try {
return file.asService().serve(ctx, req);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
}));
}
@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
return HttpResponse.from(
first.findFile(ctx, req)
.readAttributes(ctx.blockingTaskExecutor())
.thenApply(firstAttrs -> {
try {
if (firstAttrs != null) {
return first.serve(ctx, req);
}
return second.serve(ctx, req);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
}));
}
@Override
public CompletableFuture<HttpFileAttributes> readAttributes(Executor fileReadExecutor) {
requireNonNull(fileReadExecutor, "fileReadExecutor");
if (attrsFuture != null) {
return attrsFuture;
}
return attrsFuture = CompletableFuture.supplyAsync(() -> {
try {
final URLConnection conn = url.openConnection();
final long length = conn.getContentLengthLong();
final long lastModifiedMillis = conn.getLastModified();
return new HttpFileAttributes(length, lastModifiedMillis);
} catch (IOException e) {
return Exceptions.throwUnsafely(e);
}
}, fileReadExecutor);
}
@Nullable
private HttpResponse read(Executor fileReadExecutor, ByteBufAllocator alloc,
@Nullable HttpFileAttributes attrs) {
final ResponseHeaders headers = readHeaders(attrs);
if (headers == null) {
return null;
}
final long length = attrs.length();
if (length == 0) {
// No need to stream an empty file.
return HttpResponse.of(headers);
}
try {
return doRead(headers, length, fileReadExecutor, alloc);
} catch (IOException e) {
return Exceptions.throwUnsafely(e);
}
}
@Override
public HttpResponse handleException(ServiceRequestContext ctx, HttpRequest req, Throwable cause) {
if (cause instanceof IllegalArgumentException) {
if (needsToWarn()) {
logger.warn("{} Failed processing a request:", ctx, cause);
}
return HttpResponse.of(HttpStatus.BAD_REQUEST);
}
if (cause instanceof HttpStatusException) {
return HttpResponse.of(((HttpStatusException) cause).httpStatus());
}
if (cause instanceof HttpResponseException) {
return ((HttpResponseException) cause).httpResponse();
}
if (needsToWarn() && !Exceptions.isExpected(cause)) {
logger.warn("{} Unhandled exception from an annotated service:", ctx, cause);
}
return HttpResponse.of(HttpStatus.INTERNAL_SERVER_ERROR);
}
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
logger.debug("{} PING write successful", channel);
final EventLoop el = channel.eventLoop();
shutdownFuture = el.schedule(shutdownRunnable, pingIdleTimeNanos, TimeUnit.NANOSECONDS);
pingState = PingState.PENDING_PING_ACK;
resetStopwatch();
} else {
// Mostly because the channel is already closed. So ignore and change state to IDLE.
// If the channel is closed, we change state to SHUTDOWN on destroy.
if (!future.isCancelled() && Exceptions.isExpected(future.cause())) {
logger.debug("{} PING write failed", channel, future.cause());
}
if (pingState != PingState.SHUTDOWN) {
pingState = PingState.IDLE;
}
}
}
/**
* Creates a new {@link RpcResponse} that is completed successfully or exceptionally based on the
* completion of the specified {@link CompletionStage}.
*/
static RpcResponse from(CompletionStage<?> stage) {
requireNonNull(stage, "stage");
final CompletableRpcResponse res = new CompletableRpcResponse();
stage.handle((value, cause) -> {
if (cause != null) {
res.completeExceptionally(cause);
} else if (value instanceof RpcResponse) {
((RpcResponse) value).handle((rpcResponseResult, rpcResponseCause) -> {
if (rpcResponseCause != null) {
res.completeExceptionally(Exceptions.peel(rpcResponseCause));
} else {
res.complete(rpcResponseResult);
}
return null;
});
} else {
res.complete(value);
}
return null;
});
return res;
}
@Test
void timeout() {
final DynamicEndpointGroup group = new DynamicEndpointGroup();
final ClientRequestContext ctx = ClientRequestContext.of(HttpRequest.of(HttpMethod.GET, "/"));
final CompletableFuture<Endpoint> future =
newSelector(group).select(ctx, ctx.eventLoop(), 1000)
.handle((res, cause) -> {
// Must be invoked from the event loop thread.
assertThat(ctx.eventLoop().inEventLoop()).isTrue();
if (cause != null) {
Exceptions.throwUnsafely(cause);
}
return res;
});
assertThat(future).isNotDone();
final Stopwatch stopwatch = Stopwatch.createStarted();
assertThat(future.join()).isNull();
assertThat(stopwatch.elapsed(TimeUnit.MILLISECONDS)).isGreaterThan(900);
}
@Override
protected HttpResponse doPost(ServiceRequestContext ctx, HttpRequest req) {
final CompletableFuture<HttpResponse> responseFuture = new CompletableFuture<>();
final HttpResponse res = HttpResponse.from(responseFuture);
req.subscribe(new StreamConsumer(ctx.eventLoop(), slow) {
@Override
public void onError(Throwable cause) {
responseFuture.complete(
HttpResponse.of(
HttpStatus.INTERNAL_SERVER_ERROR,
MediaType.PLAIN_TEXT_UTF_8,
Exceptions.traceText(cause)));
}
@Override
public void onComplete() {
responseFuture.complete(
HttpResponse.of(
HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, "%d", numReceivedBytes()));
}
});
return res;
}
private <T> CompletableFuture<T> watch(Revision lastKnownRevision, long timeoutMillis,
String path, QueryType queryType,
BiFunction<AggregatedHttpResponse, QueryType, T> func) {
final RequestHeadersBuilder builder = headersBuilder(HttpMethod.GET, path);
builder.set(HttpHeaderNames.IF_NONE_MATCH, lastKnownRevision.text())
.set(HttpHeaderNames.PREFER, "wait=" + LongMath.saturatedAdd(timeoutMillis, 999) / 1000L);
try (SafeCloseable ignored = Clients.withContextCustomizer(ctx -> {
final long responseTimeoutMillis = ctx.responseTimeoutMillis();
final long adjustmentMillis = WatchTimeout.availableTimeout(timeoutMillis, responseTimeoutMillis);
if (responseTimeoutMillis > 0) {
ctx.setResponseTimeoutMillis(TimeoutMode.EXTEND, adjustmentMillis);
} else {
ctx.setResponseTimeoutMillis(adjustmentMillis);
}
})) {
return client.execute(builder.build()).aggregate()
.handle((res, cause) -> {
if (cause == null) {
return func.apply(res, queryType);
}
if ((cause instanceof ClosedStreamException) &&
client.options().factory().isClosing()) {
// A user closed the client factory while watching.
return null;
}
return Exceptions.throwUnsafely(cause);
});
}
}
private static <T> CompletableFuture<T> run(ThriftCall<T> call) {
final ThriftFuture<T> future = new ThriftFuture<>();
try {
call.apply(future);
return future.exceptionally(cause -> Exceptions.throwUnsafely(convertCause(cause)));
} catch (Exception e) {
return CompletableFutures.exceptionallyCompletedFuture(convertCause(e));
}
}
/**
* Adds a {@link RepositoryMetadata} of the specified {@code repoName} to the specified {@code projectName}
* with the specified {@link PerRolePermissions}.
*/
public CompletableFuture<Revision> addRepo(Author author, String projectName, String repoName,
PerRolePermissions permission) {
requireNonNull(author, "author");
requireNonNull(projectName, "projectName");
requireNonNull(repoName, "repoName");
requireNonNull(permission, "permission");
final JsonPointer path = JsonPointer.compile("/repos" + encodeSegment(repoName));
final RepositoryMetadata newRepositoryMetadata = new RepositoryMetadata(repoName,
UserAndTimestamp.of(author),
permission);
final Change<JsonNode> change =
Change.ofJsonPatch(METADATA_JSON,
asJsonArray(new TestAbsenceOperation(path),
new AddOperation(path,
Jackson.valueToTree(newRepositoryMetadata))));
final String commitSummary =
"Add a repo '" + newRepositoryMetadata.id() + "' to the project '" + projectName + '\'';
return metadataRepo.push(projectName, Project.REPO_DOGMA, author, commitSummary, change)
.handle((revision, cause) -> {
if (cause != null) {
if (Exceptions.peel(cause) instanceof ChangeConflictException) {
throw new RepositoryExistsException(repoName);
} else {
return Exceptions.throwUnsafely(cause);
}
}
return revision;
});
}
private void push(String projectName, String repoName, Author author, String commitSummary,
Supplier<CompletionStage<HolderWithRevision<Change<?>>>> changeSupplier,
CompletableFuture<Revision> future) {
changeSupplier.get().thenAccept(changeWithRevision -> {
final Revision revision = changeWithRevision.revision();
final Change<?> change = changeWithRevision.object();
push(projectName, repoName, author, commitSummary, change, revision)
.thenAccept(future::complete)
.exceptionally(voidFunction(cause -> {
cause = Exceptions.peel(cause);
if (cause instanceof ChangeConflictException) {
final Revision latestRevision;
try {
latestRevision = projectManager().get(projectName).repos().get(repoName)
.normalizeNow(Revision.HEAD);
} catch (Throwable cause1) {
future.completeExceptionally(cause1);
return;
}
if (revision.equals(latestRevision)) {
future.completeExceptionally(cause);
return;
}
// Try again.
push(projectName, repoName, author, commitSummary, changeSupplier, future);
} else if (cause instanceof RedundantChangeException) {
future.complete(revision);
} else {
future.completeExceptionally(cause);
}
}));
}).exceptionally(voidFunction(future::completeExceptionally));
}
Revision normalize(Repository repository) {
requireNonNull(repository, "repository");
try {
return repository.normalizeNow(Revision.HEAD);
} catch (Throwable cause) {
return Exceptions.throwUnsafely(cause);
}
}
@SuppressWarnings("unchecked")
static <T> T convertWithJackson(Entry<?> entry, Class<T> clazz) {
requireNonNull(entry, "entry");
requireNonNull(clazz, "clazz");
try {
return Jackson.treeToValue(((Entry<JsonNode>) entry).content(), clazz);
} catch (Throwable cause) {
return Exceptions.throwUnsafely(cause);
}
}
private HttpResponse serveUserRepo(ServiceRequestContext ctx, HttpRequest req,
MetadataService mds, User user,
String projectName, String repoName) throws Exception {
final CompletionStage<Collection<Permission>> f;
try {
f = mds.findPermissions(projectName, repoName, user);
} catch (Throwable cause) {
return handleException(ctx, cause);
}
return HttpResponse.from(f.handle((permission, cause) -> {
if (cause != null) {
return handleException(ctx, cause);
}
if (!permission.contains(requiredPermission)) {
return HttpApiUtil.throwResponse(
ctx, HttpStatus.FORBIDDEN,
"You must have %s permission for repository '%s/%s'.",
requiredPermission, projectName, repoName);
}
try {
return unwrap().serve(ctx, req);
} catch (Exception e) {
return Exceptions.throwUnsafely(e);
}
}));
}
static HttpResponse handleException(ServiceRequestContext ctx, Throwable cause) {
cause = Exceptions.peel(cause);
if (cause instanceof RepositoryNotFoundException ||
cause instanceof ProjectNotFoundException) {
return HttpApiUtil.newResponse(ctx, HttpStatus.NOT_FOUND, cause);
} else {
return Exceptions.throwUnsafely(cause);
}
}
@Override
public CompletionStage<Boolean> authorize(ServiceRequestContext ctx, HttpRequest data) {
final OAuth2Token token = AuthTokenExtractors.oAuth2().apply(data.headers());
if (token == null || !Tokens.isValidSecret(token.accessToken())) {
return completedFuture(false);
}
final CompletableFuture<Boolean> res = new CompletableFuture<>();
tokenLookupFunc.apply(token.accessToken())
.thenAccept(appToken -> {
if (appToken != null && appToken.isActive()) {
final StringBuilder login = new StringBuilder(appToken.appId());
final SocketAddress ra = ctx.remoteAddress();
if (ra instanceof InetSocketAddress) {
login.append('@').append(((InetSocketAddress) ra).getHostString());
}
AuthUtil.setCurrentUser(
ctx, new UserWithToken(login.toString(), appToken));
res.complete(true);
} else {
res.complete(false);
}
})
// Should be authorized by the next authorizer.
.exceptionally(voidFunction(cause -> {
cause = Exceptions.peel(cause);
if (!(cause instanceof IllegalArgumentException)) {
logger.warn("Application token authorization failed: {}",
token.accessToken(), cause);
}
res.complete(false);
}));
return res;
}