All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.fabric8.kubernetes.client.jetty.JettyHttpClient Maven / Gradle / Ivy
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* 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 io.fabric8.kubernetes.client.jetty;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.http.AsyncBody;
import io.fabric8.kubernetes.client.http.AsyncBody.Consumer;
import io.fabric8.kubernetes.client.http.HttpResponse;
import io.fabric8.kubernetes.client.http.StandardHttpClient;
import io.fabric8.kubernetes.client.http.StandardHttpClientBuilder;
import io.fabric8.kubernetes.client.http.StandardHttpHeaders;
import io.fabric8.kubernetes.client.http.StandardHttpRequest;
import io.fabric8.kubernetes.client.http.StandardHttpRequest.BodyContent;
import io.fabric8.kubernetes.client.http.StandardHttpRequest.ByteArrayBodyContent;
import io.fabric8.kubernetes.client.http.StandardHttpRequest.InputStreamBodyContent;
import io.fabric8.kubernetes.client.http.StandardHttpRequest.StringBodyContent;
import io.fabric8.kubernetes.client.http.StandardWebSocketBuilder;
import io.fabric8.kubernetes.client.http.WebSocket;
import io.fabric8.kubernetes.client.http.WebSocket.Listener;
import io.fabric8.kubernetes.client.http.WebSocketResponse;
import io.fabric8.kubernetes.client.utils.Utils;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.BytesRequestContent;
import org.eclipse.jetty.client.util.InputStreamRequestContent;
import org.eclipse.jetty.client.util.StringRequestContent;
import org.eclipse.jetty.websocket.api.exceptions.UpgradeException;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static io.fabric8.kubernetes.client.http.BufferUtil.copy;
import static io.fabric8.kubernetes.client.http.StandardMediaTypes.APPLICATION_OCTET_STREAM;
import static io.fabric8.kubernetes.client.http.StandardMediaTypes.TEXT_PLAIN;
public class JettyHttpClient extends StandardHttpClient {
private final HttpClient jetty;
private final WebSocketClient jettyWs;
public JettyHttpClient(StandardHttpClientBuilder builder,
HttpClient jetty, WebSocketClient jettyWs) {
this(builder, jetty, jettyWs, new AtomicBoolean());
}
public JettyHttpClient(StandardHttpClientBuilder builder,
HttpClient jetty, WebSocketClient jettyWs, AtomicBoolean closed) {
super(builder, closed);
this.jetty = jetty;
this.jettyWs = jettyWs;
}
@Override
public void doClose() {
try {
jetty.stop();
jettyWs.stop();
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(e);
}
}
@Override
public CompletableFuture> consumeBytesDirect(StandardHttpRequest request,
Consumer> consumer) {
return new JettyAsyncResponseListener(request) {
@Override
protected void onContent(ByteBuffer content) throws Exception {
// we must clone as the buffer can be reused by the byte consumer
consumer.consume(Collections.singletonList(copy(content)), this);
}
}.listen(newRequest(request));
}
private Request newRequest(StandardHttpRequest originalRequest) {
try {
jetty.start();
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(e);
}
final var requestBuilder = originalRequest.newBuilder();
final var request = requestBuilder.build();
var jettyRequest = jetty.newRequest(request.uri()).method(request.method());
if (originalRequest.getTimeout() != null) {
jettyRequest.timeout(originalRequest.getTimeout().toMillis(), TimeUnit.MILLISECONDS);
}
jettyRequest.headers(m -> request.headers().forEach(m::put));
final var contentType = Optional.ofNullable(request.getContentType());
BodyContent body = request.body();
if (body != null) {
if (body instanceof StringBodyContent) {
jettyRequest.body(new StringRequestContent(contentType.orElse(TEXT_PLAIN), ((StringBodyContent) body).getContent()));
} else if (body instanceof ByteArrayBodyContent) {
jettyRequest.body(
new BytesRequestContent(contentType.orElse(APPLICATION_OCTET_STREAM), ((ByteArrayBodyContent) body).getContent()));
} else if (body instanceof InputStreamBodyContent) {
InputStreamBodyContent bodyContent = (InputStreamBodyContent) body;
if (bodyContent.getLength() >= 0) {
jettyRequest.headers(m -> m.put(StandardHttpHeaders.CONTENT_LENGTH, Long.toString(bodyContent.getLength())));
}
jettyRequest
.body(new InputStreamRequestContent(contentType.orElse(APPLICATION_OCTET_STREAM), bodyContent.getContent()));
} else {
throw new AssertionError("Unsupported body content");
}
}
if (request.isExpectContinue()) {
jettyRequest.headers(m -> m.put(StandardHttpHeaders.EXPECT, StandardHttpHeaders.EXPECT_CONTINUE));
}
return jettyRequest;
}
@Override
public CompletableFuture buildWebSocketDirect(StandardWebSocketBuilder standardWebSocketBuilder,
Listener listener) {
try {
jettyWs.start();
StandardHttpRequest request = standardWebSocketBuilder.asHttpRequest();
final ClientUpgradeRequest cur = new ClientUpgradeRequest();
if (Utils.isNotNullOrEmpty(standardWebSocketBuilder.getSubprotocol())) {
cur.setSubProtocols(standardWebSocketBuilder.getSubprotocol());
}
cur.setHeaders(request.headers());
if (request.getTimeout() != null) {
cur.setTimeout(request.getTimeout().toMillis(), TimeUnit.MILLISECONDS);
}
// Extra-future required because we can't Map the UpgradeException to a WebSocketHandshakeException easily
final CompletableFuture future = new CompletableFuture<>();
final JettyWebSocket webSocket = new JettyWebSocket(listener);
jettyWs.connect(webSocket, Objects.requireNonNull(WebSocket.toWebSocketUri(request.uri())), cur)
.whenComplete((s, ex) -> {
if (ex != null) {
if (ex instanceof CompletionException && ex.getCause() instanceof UpgradeException) {
future.complete(JettyWebSocket.toWebSocketResponse(request, (UpgradeException) ex.getCause()));
} else if (ex instanceof UpgradeException) {
future.complete(JettyWebSocket.toWebSocketResponse(request, (UpgradeException) ex));
} else {
future.completeExceptionally(ex);
}
} else {
future.complete(JettyWebSocket.toWebSocketResponse(request, webSocket, s));
}
});
return future;
} catch (Exception e) {
throw KubernetesClientException.launderThrowable(e);
}
}
HttpClient getJetty() {
return jetty;
}
WebSocketClient getJettyWs() {
return jettyWs;
}
}