use of io.kubernetes.client.informer.SharedInformerFactory in project java by kubernetes-client.
the class InformerExample method main.
public static void main(String[] args) throws Exception {
CoreV1Api coreV1Api = new CoreV1Api();
ApiClient apiClient = coreV1Api.getApiClient();
OkHttpClient httpClient = apiClient.getHttpClient().newBuilder().readTimeout(0, TimeUnit.SECONDS).build();
apiClient.setHttpClient(httpClient);
SharedInformerFactory factory = new SharedInformerFactory(apiClient);
// Node informer
SharedIndexInformer<V1Node> nodeInformer = factory.sharedIndexInformerFor(// the informer-factory.
(CallGeneratorParams params) -> {
return coreV1Api.listNodeCall(null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
}, V1Node.class, V1NodeList.class);
nodeInformer.addEventHandler(new ResourceEventHandler<V1Node>() {
@Override
public void onAdd(V1Node node) {
System.out.printf("%s node added!\n", node.getMetadata().getName());
}
@Override
public void onUpdate(V1Node oldNode, V1Node newNode) {
System.out.printf("%s => %s node updated!\n", oldNode.getMetadata().getName(), newNode.getMetadata().getName());
}
@Override
public void onDelete(V1Node node, boolean deletedFinalStateUnknown) {
System.out.printf("%s node deleted!\n", node.getMetadata().getName());
}
});
factory.startAllRegisteredInformers();
V1Node nodeToCreate = new V1Node();
V1ObjectMeta metadata = new V1ObjectMeta();
metadata.setName("noxu");
nodeToCreate.setMetadata(metadata);
V1Node createdNode = coreV1Api.createNode(nodeToCreate, null, null, null, null);
Thread.sleep(3000);
Lister<V1Node> nodeLister = new Lister<V1Node>(nodeInformer.getIndexer());
V1Node node = nodeLister.get("noxu");
System.out.printf("noxu created! %s\n", node.getMetadata().getCreationTimestamp());
factory.stopAllRegisteredInformers();
Thread.sleep(3000);
System.out.println("informer stopped..");
}
use of io.kubernetes.client.informer.SharedInformerFactory in project java by kubernetes-client.
the class ControllerManagerTest method testControllerStartShutdown.
@Test
public void testControllerStartShutdown() {
DummyController dummy1 = new DummyController();
DummyController dummy2 = new DummyController();
ControllerManager cm = new ControllerManager(new SharedInformerFactory(), dummy1, dummy2);
cm.run();
assertTrue(dummy1.started);
assertTrue(dummy2.started);
cm.shutdown();
assertTrue(dummy1.stopped);
assertTrue(dummy2.stopped);
}
use of io.kubernetes.client.informer.SharedInformerFactory 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.informer.SharedInformerFactory in project java by kubernetes-client.
the class DefaultSharedIndexInformerWireMockTest method testAllNamespacedPodInformerNormalBehavior.
@Test
public void testAllNamespacedPodInformerNormalBehavior() throws InterruptedException {
CoreV1Api coreV1Api = new CoreV1Api(client);
String startRV = "1000";
String endRV = "1001";
V1PodList podList = new V1PodList().metadata(new V1ListMeta().resourceVersion(startRV)).items(Arrays.asList());
stubFor(get(urlPathEqualTo("/api/v1/pods")).withQueryParam("watch", equalTo("false")).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(new JSON().serialize(podList))));
Watch.Response<V1Pod> watchResponse = new Watch.Response<>(EventType.ADDED.name(), new V1Pod().metadata(new V1ObjectMeta().namespace(namespace).name(podName).resourceVersion(endRV).labels(Collections.singletonMap("foo", "bar")).annotations(Collections.singletonMap("foo", "bar"))));
stubFor(get(urlPathEqualTo("/api/v1/pods")).withQueryParam("watch", equalTo("true")).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(new JSON().serialize(watchResponse))));
SharedInformerFactory factory = new SharedInformerFactory();
SharedIndexInformer<V1Pod> podInformer = factory.sharedIndexInformerFor((CallGeneratorParams params) -> {
try {
return coreV1Api.listPodForAllNamespacesCall(null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
} catch (ApiException e) {
throw new RuntimeException(e);
}
}, V1Pod.class, V1PodList.class);
podInformer.setTransform((obj) -> {
// deepcopy
String json = new JSON().serialize(obj);
V1Pod pod = new JSON().deserialize(json, V1Pod.class);
// remove pod annotations
pod.getMetadata().setAnnotations(null);
return pod;
});
AtomicBoolean foundExistingPod = new AtomicBoolean(false);
AtomicBoolean transformed = new AtomicBoolean(false);
AtomicBoolean setTransformAfterStarted = new AtomicBoolean(false);
podInformer.addEventHandler(new ResourceEventHandler<V1Pod>() {
@Override
public void onAdd(V1Pod obj) {
if (podName.equals(obj.getMetadata().getName()) && namespace.equals(obj.getMetadata().getNamespace())) {
foundExistingPod.set(true);
}
V1ObjectMeta metadata = obj.getMetadata();
// check if the object was transformed
if (metadata.getLabels().get("foo").equals("bar") && metadata.getAnnotations() == null) {
transformed.set(true);
}
}
@Override
public void onUpdate(V1Pod oldObj, V1Pod newObj) {
}
@Override
public void onDelete(V1Pod obj, boolean deletedFinalStateUnknown) {
}
});
factory.startAllRegisteredInformers();
Thread.sleep(1000);
// can not set transform func if the informer has started
try {
podInformer.setTransform((obj) -> new V1Pod());
setTransformAfterStarted.set(true);
} catch (IllegalStateException e) {
}
assertTrue(foundExistingPod.get());
assertTrue(transformed.get());
assertFalse(setTransformAfterStarted.get());
assertEquals(endRV, podInformer.lastSyncResourceVersion());
verify(1, getRequestedFor(urlPathEqualTo("/api/v1/pods")).withQueryParam("watch", equalTo("false")));
verify(moreThan(1), getRequestedFor(urlPathEqualTo("/api/v1/pods")).withQueryParam("watch", equalTo("true")));
factory.stopAllRegisteredInformers();
}
use of io.kubernetes.client.informer.SharedInformerFactory in project java by kubernetes-client.
the class DefaultSharedIndexInformerWireMockTest method testInformerReListWatchOnWatchConflict.
@Test
public void testInformerReListWatchOnWatchConflict() throws InterruptedException {
CoreV1Api coreV1Api = new CoreV1Api(client);
String startRV = "1000";
V1PodList podList = new V1PodList().metadata(new V1ListMeta().resourceVersion(startRV)).items(Arrays.asList());
stubFor(get(urlPathEqualTo("/api/v1/namespaces/" + namespace + "/pods")).withQueryParam("watch", equalTo("false")).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(new JSON().serialize(podList))));
Watch.Response<V1Pod> watchResponse = new Watch.Response<>(EventType.ERROR.name(), new V1Status().apiVersion("v1").kind("Status").code(409));
stubFor(get(urlPathEqualTo("/api/v1/namespaces/" + namespace + "/pods")).withQueryParam("watch", equalTo("true")).withQueryParam("resourceVersion", equalTo(startRV)).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(new JSON().serialize(watchResponse))));
SharedInformerFactory factory = new SharedInformerFactory();
SharedIndexInformer<V1Pod> podInformer = factory.sharedIndexInformerFor((CallGeneratorParams params) -> {
try {
return coreV1Api.listNamespacedPodCall(namespace, null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
} catch (ApiException e) {
throw new RuntimeException(e);
}
}, V1Pod.class, V1PodList.class);
factory.startAllRegisteredInformers();
// Sleep mroe than 1s so that informer can perform multiple rounds of list-watch
Thread.sleep(3000);
verify(moreThan(1), getRequestedFor(urlPathEqualTo("/api/v1/namespaces/" + namespace + "/pods")).withQueryParam("watch", equalTo("false")));
verify(moreThan(1), getRequestedFor(urlPathEqualTo("/api/v1/namespaces/" + namespace + "/pods")).withQueryParam("watch", equalTo("true")));
factory.stopAllRegisteredInformers();
}
Aggregations