use of io.kubernetes.client.extended.controller.reconciler.Reconciler in project java by kubernetes-client.
the class DefaultControllerTest method testControllerKeepsWorkingWhenReconcilerAbortsWithRuntimeException.
@Test(timeout = 90000)
public void testControllerKeepsWorkingWhenReconcilerAbortsWithRuntimeException() throws InterruptedException {
AtomicBoolean aborts = new AtomicBoolean(true);
AtomicBoolean resumed = new AtomicBoolean(false);
List<Request> finishedRequests = new ArrayList<>();
final Semaphore latch = new Semaphore(1);
DefaultController testController = new DefaultController("", new Reconciler() {
@Override
public Result reconcile(Request request) {
try {
if (aborts.get()) {
throw new RuntimeException("Oops!!");
}
resumed.set(true);
finishedRequests.add(request);
return new Result(false);
} finally {
latch.release();
}
}
}, workQueue);
testController.setWorkerCount(1);
testController.setWorkerThreadPool(Executors.newScheduledThreadPool(1));
controllerThead.submit(testController::run);
Request request1 = new Request("test1");
workQueue.add(request1);
latch.acquire();
aborts.set(false);
// emit another event, the previous one has been backoff'd
Request request2 = new Request("test2");
workQueue.add(request2);
latch.acquire();
testController.shutdown();
assertTrue(resumed.get());
assertTrue(finishedRequests.size() >= 1);
}
use of io.kubernetes.client.extended.controller.reconciler.Reconciler in project java by kubernetes-client.
the class DefaultControllerBuilderTest method testBuildWatchShouldWorkIfInformerPresent.
@Test
public void testBuildWatchShouldWorkIfInformerPresent() {
CoreV1Api api = new CoreV1Api();
informerFactory.sharedIndexInformerFor((CallGeneratorParams params) -> {
return api.listPodForAllNamespacesCall(null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
}, V1Pod.class, V1PodList.class);
ControllerBuilder.defaultBuilder(informerFactory).watch((workQueue) -> ControllerBuilder.controllerWatchBuilder(V1Pod.class, workQueue).build()).withReconciler(new Reconciler() {
@Override
public Result reconcile(Request request) {
return new Result(false);
}
}).build();
}
use of io.kubernetes.client.extended.controller.reconciler.Reconciler in project java by kubernetes-client.
the class DefaultControllerBuilderTest method testControllerBuilderCustomizationShouldWork.
@Test
public void testControllerBuilderCustomizationShouldWork() {
String testName = "test-controller";
int testWorkerCount = 1024;
ExecutorService threadPool = Executors.newCachedThreadPool();
ControllerBuilder.defaultBuilder(informerFactory).withName(testName).withWorkerCount(testWorkerCount).withWorkQueue(null).withReconciler(new Reconciler() {
@Override
public Result reconcile(Request request) {
return new Result(false);
}
}).build();
}
use of io.kubernetes.client.extended.controller.reconciler.Reconciler in project java by kubernetes-client.
the class KubernetesControllerFactory method buildController.
private Controller buildController(SharedInformerFactory sharedInformerFactory, Reconciler r) throws BeansException {
KubernetesReconciler kubernetesReconciler = r.getClass().getAnnotation(KubernetesReconciler.class);
String reconcilerName = kubernetesReconciler.value();
KubernetesReconcilerWatches watches = kubernetesReconciler.watches();
DefaultControllerBuilder builder = ControllerBuilder.defaultBuilder(sharedInformerFactory);
RateLimitingQueue<Request> workQueue = new DefaultRateLimitingQueue<>();
builder = builder.withWorkQueue(workQueue);
Map<Class, AddFilterAdaptor> addFilters = getAddFilters(watches, r);
Map<Class, UpdateFilterAdaptor> updateFilters = getUpdateFilters(watches, r);
Map<Class, DeleteFilterAdaptor> deleteFilters = getDeleteFilters(watches, r);
List<ReadyFuncAdaptor> readyFuncs = getReadyFuncs(r);
for (KubernetesReconcilerWatch watch : watches.value()) {
try {
Function<? extends KubernetesObject, Request> workQueueKeyFunc;
try {
workQueueKeyFunc = watch.workQueueKeyFunc().getConstructor(WorkQueue.class).newInstance(workQueue);
} catch (NoSuchMethodException e) {
workQueueKeyFunc = watch.workQueueKeyFunc().newInstance();
} catch (InvocationTargetException e) {
throw new BeanCreationException("Failed instantiating controller watch: " + e.getMessage());
}
final Function<? extends KubernetesObject, Request> finalWorkQueueKeyFunc = workQueueKeyFunc;
builder = builder.watch((q) -> {
return ControllerBuilder.controllerWatchBuilder(watch.apiTypeClass(), q).withOnAddFilter(addFilters.get(watch.apiTypeClass())).withOnUpdateFilter(updateFilters.get(watch.apiTypeClass())).withOnDeleteFilter(deleteFilters.get(watch.apiTypeClass())).withWorkQueueKeyFunc(finalWorkQueueKeyFunc).withResyncPeriod(Duration.ofMillis(watch.resyncPeriodMillis())).build();
});
for (Supplier<Boolean> readyFunc : readyFuncs) {
builder = builder.withReadyFunc(readyFunc);
}
} catch (IllegalAccessException | InstantiationException e) {
throw new BeanCreationException("Failed instantiating controller: " + e.getMessage());
}
}
builder = builder.withWorkerCount(kubernetesReconciler.workerCount());
return builder.withReconciler(r).withName(reconcilerName).build();
}
use of io.kubernetes.client.extended.controller.reconciler.Reconciler in project java by kubernetes-client.
the class DefaultControllerBuilderTest method testBuildWatchEventNotificationShouldWork.
@Test
public void testBuildWatchEventNotificationShouldWork() throws InterruptedException {
V1PodList podList = new V1PodList().metadata(new V1ListMeta().resourceVersion("0")).items(Arrays.asList(new V1Pod().metadata(new V1ObjectMeta().name("test-pod1")).spec(new V1PodSpec().hostname("hostname1"))));
stubFor(get(urlPathEqualTo("/api/v1/pods")).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(new JSON().serialize(podList))));
CoreV1Api api = new CoreV1Api(client);
SharedIndexInformer<V1Pod> podInformer = informerFactory.sharedIndexInformerFor((CallGeneratorParams params) -> {
return api.listPodForAllNamespacesCall(null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
}, V1Pod.class, V1PodList.class);
List<Request> keyFuncReceivingRequests = new ArrayList<>();
Function<V1Pod, Request> podKeyFunc = (V1Pod pod) -> {
// twisting pod name key
Request request = new Request(pod.getSpec().getHostname() + "/" + pod.getMetadata().getName());
keyFuncReceivingRequests.add(request);
return request;
};
List<Request> controllerReceivingRequests = new ArrayList<>();
final Semaphore latch = new Semaphore(1);
latch.acquire();
final Controller testController = ControllerBuilder.defaultBuilder(informerFactory).withReconciler(new Reconciler() {
@Override
public Result reconcile(Request request) {
controllerReceivingRequests.add(request);
latch.release();
return new Result(false);
}
}).watch((workQueue) -> ControllerBuilder.controllerWatchBuilder(V1Pod.class, workQueue).withWorkQueueKeyFunc(podKeyFunc).build()).build();
controllerThead.submit(testController::run);
informerFactory.startAllRegisteredInformers();
// Wait for the request to be processed.
latch.acquire(1);
Request expectedRequest = new Request("hostname1/test-pod1");
assertEquals(1, keyFuncReceivingRequests.size());
assertEquals(expectedRequest, keyFuncReceivingRequests.get(0));
assertEquals(1, controllerReceivingRequests.size());
assertEquals(expectedRequest, controllerReceivingRequests.get(0));
}
Aggregations