use of io.kubernetes.client.openapi.ApiException in project java by kubernetes-client.
the class Exec method exec.
/**
* A convenience method. Executes a command remotely on a pod and monitors for events in that
* execution. The monitored events are: <br>
* - connection established (onOpen) <br>
* - connection closed (onClosed) <br>
* - execution error occurred (onError) <br>
* This method also allows to specify a MAX timeout for the execution and returns a future in
* order to monitor the execution flow. <br>
* onError and onClosed callbacks are invoked asynchronously, in a separate thread. <br>
*
* @param namespace a namespace the target pod "lives" in
* @param podName a name of the pod to exec the command on
* @param onOpen a callback invoked upon the connection established event.
* @param onClosed a callback invoked upon the process termination. Return code might not always
* be there. N.B. this callback is invoked before the returned {@link Future} is completed.
* @param onError a callback to handle k8s errors (NOT the command errors/stderr!)
* @param timeoutMs timeout in milliseconds for the execution. I.e. the execution will take this
* many ms or less. If the timeout command is running longer than the allowed timeout, the
* command will be "asked" to terminate gracefully. If the command is still running after the
* grace period, the sigkill will be issued. If null is passed, the timeout will not be used
* and will wait for process to exit itself.
* @param tty whether you need tty to pipe the data. TTY mode will trim some binary data in order
* to make it possible to show on screen (tty)
* @param command a tokenized command to run on the pod
* @return a {@link Future} promise representing this execution. Unless something goes south, the
* promise will contain the process return exit code. If the timeoutMs is non-null and the
* timeout expires before the process exits, promise will contain {@link Integer#MAX_VALUE}.
* @throws IOException
*/
public Future<Integer> exec(String namespace, String podName, Consumer<IOTrio> onOpen, BiConsumer<Integer, IOTrio> onClosed, BiConsumer<Throwable, IOTrio> onError, Long timeoutMs, boolean tty, String... command) throws IOException {
CompletableFuture<Integer> future = new CompletableFuture<>();
IOTrio io = new IOTrio();
String cmdStr = Arrays.toString(command);
BiConsumer<Throwable, IOTrio> errHandler = (err, errIO) -> {
if (onError != null) {
onError.accept(err, errIO);
}
};
try {
Process process = exec(namespace, podName, command, null, true, tty);
io.onClose((code, timeout) -> {
process.destroy();
waitForProcessToExit(process, timeout, cmdStr, err -> errHandler.accept(err, io));
// processWaitingThread will handle the rest
});
io.setStdin(process.getOutputStream());
io.setStdout(process.getInputStream());
io.setStderr(process.getErrorStream());
runAsync("Process-Waiting-Thread-" + command[0] + "-" + podName, () -> {
Supplier<Integer> returnCode = process::exitValue;
try {
log.debug("Waiting for process to close in {} ms: {}", timeoutMs, cmdStr);
boolean beforeTimout = waitForProcessToExit(process, timeoutMs, cmdStr, err -> errHandler.accept(err, io));
if (!beforeTimout) {
returnCode = () -> Integer.MAX_VALUE;
}
} catch (Exception e) {
errHandler.accept(e, io);
}
log.debug("process.onExit({}): {}", returnCode.get(), cmdStr);
if (onClosed != null) {
onClosed.accept(returnCode.get(), io);
}
future.complete(returnCode.get());
});
if (onOpen != null) {
onOpen.accept(io);
}
} catch (ApiException e) {
errHandler.accept(e, io);
future.completeExceptionally(e);
}
return future;
}
use of io.kubernetes.client.openapi.ApiException in project java by kubernetes-client.
the class ProtoClient method request.
/**
* Generic protocol buffer based HTTP request. Not intended for general consumption, but public
* for advance use cases.
*
* @param builder The appropriate Builder for the object received from the request.
* @param method The HTTP method (e.g. GET) for this request.
* @param path The URL path to call (e.g. /api/v1/namespaces/default/pods/pod-name)
* @param body The body to send with the request (optional)
* @param apiVersion The 'apiVersion' to use when encoding, required if body is non-null, ignored
* otherwise.
* @param kind The 'kind' field to use when encoding, required if body is non-null, ignored
* otherwise.
* @return An ObjectOrStatus which contains the Object requested, or a Status about the request.
*/
public <T extends Message> ObjectOrStatus<T> request(T.Builder builder, String path, String method, T body, String apiVersion, String kind) throws ApiException, IOException {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", MEDIA_TYPE);
headers.put("Accept", MEDIA_TYPE);
String[] localVarAuthNames = new String[] { "BearerToken" };
Request request = apiClient.buildRequest(path, method, new ArrayList<Pair>(), new ArrayList<Pair>(), null, headers, new HashMap<String, String>(), new HashMap<String, Object>(), localVarAuthNames, null);
if (body != null) {
byte[] bytes = encode(body, apiVersion, kind);
switch(method) {
case "POST":
request = request.newBuilder().post(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build();
break;
case "PUT":
request = request.newBuilder().put(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build();
break;
case "PATCH":
request = request.newBuilder().patch(RequestBody.create(MediaType.parse(MEDIA_TYPE), bytes)).build();
break;
default:
throw new ApiException("Unknown proto client API method: " + method);
}
}
return getObjectOrStatusFromServer(builder, request);
}
use of io.kubernetes.client.openapi.ApiException in project java by kubernetes-client.
the class ReflectorRunnableTest method testReflectorRunnableShouldCaptureListNon410ApiException.
@Test
public void testReflectorRunnableShouldCaptureListNon410ApiException() throws ApiException {
ApiException expectedException = new ApiException(403, "noxu");
AtomicReference<Throwable> actualException = new AtomicReference<>();
when(listerWatcher.list(any())).thenThrow(expectedException);
ReflectorRunnable<V1Pod, V1PodList> reflectorRunnable = new ReflectorRunnable<>(V1Pod.class, listerWatcher, deltaFIFO, (apiType, t) -> {
actualException.set(t);
});
try {
Thread thread = new Thread(reflectorRunnable::run);
thread.setDaemon(true);
thread.start();
Awaitility.await().atMost(Duration.ofSeconds(1)).pollInterval(Duration.ofMillis(100)).untilAtomic(actualException, new IsEqual<>(expectedException));
} finally {
reflectorRunnable.stop();
}
}
use of io.kubernetes.client.openapi.ApiException in project java by kubernetes-client.
the class ReflectorRunnableTest method testReflectorRelistShouldHonorLastSyncResourceVersion.
@Test
public void testReflectorRelistShouldHonorLastSyncResourceVersion() {
String expectedResourceVersion = "999";
AtomicReference<String> requestedResourceVersion = new AtomicReference<>();
ReflectorRunnable<V1Pod, V1PodList> reflectorRunnable = new ReflectorRunnable<>(V1Pod.class, new ListerWatcher<V1Pod, V1PodList>() {
@Override
public V1PodList list(CallGeneratorParams params) throws ApiException {
requestedResourceVersion.set(params.resourceVersion);
return new V1PodList().metadata(new V1ListMeta().resourceVersion(expectedResourceVersion));
}
@Override
public Watchable<V1Pod> watch(CallGeneratorParams params) throws ApiException {
throw new ApiException("HTTP GONE");
}
}, deltaFIFO);
// first run
try {
Thread thread = new Thread(reflectorRunnable::run);
thread.setDaemon(true);
thread.start();
Awaitility.await().atMost(Duration.ofSeconds(1)).pollInterval(Duration.ofMillis(100)).until(() -> expectedResourceVersion.equals(reflectorRunnable.getLastSyncResourceVersion()));
} finally {
reflectorRunnable.stop();
}
// second run
try {
Thread thread = new Thread(reflectorRunnable::run);
thread.setDaemon(true);
thread.start();
Awaitility.await().atMost(Duration.ofSeconds(1)).pollInterval(Duration.ofMillis(100)).untilAtomic(requestedResourceVersion, new IsEqual<>(expectedResourceVersion));
} finally {
reflectorRunnable.stop();
}
}
use of io.kubernetes.client.openapi.ApiException in project java by kubernetes-client.
the class RetryUtilsTest method testRetryUponConflictShouldWorkWithinMaxRetry.
@Test
public void testRetryUponConflictShouldWorkWithinMaxRetry() throws ApiException {
AtomicInteger conflictCount = new AtomicInteger(2);
Object expectedReturn = new Object();
when(apiInvocation.call()).thenAnswer((stub) -> {
if (conflictCount.get() > 0) {
conflictCount.decrementAndGet();
throw new ApiException(HttpURLConnection.HTTP_CONFLICT, "");
}
return expectedReturn;
});
Object actualReturn = RetryUtils.retryUponConflict(apiInvocation, 3);
assertEquals(expectedReturn, actualReturn);
}
Aggregations