diff --git a/extensions/camel-k/client/src/main/resources/resource-handler.vm b/extensions/camel-k/client/src/main/resources/resource-handler.vm index 99c13e1343a..01cdbd17bad 100644 --- a/extensions/camel-k/client/src/main/resources/resource-handler.vm +++ b/extensions/camel-k/client/src/main/resources/resource-handler.vm @@ -29,25 +29,15 @@ package io.fabric8.camelk.client.handlers.$apiVersion; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.camelk.client.internal.$apiVersion.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -64,53 +54,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/extensions/certmanager/client/src/main/resources/resource-handler.vm b/extensions/certmanager/client/src/main/resources/resource-handler.vm index 9829e816a98..ace8d96d350 100644 --- a/extensions/certmanager/client/src/main/resources/resource-handler.vm +++ b/extensions/certmanager/client/src/main/resources/resource-handler.vm @@ -30,25 +30,15 @@ package io.fabric8.certmanager.${group}.${apiVersion}.handlers; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.certmanager.client.${group}.${apiVersion}.internal.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -65,53 +55,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/extensions/chaosmesh/client/src/main/resources/resource-handler.vm b/extensions/chaosmesh/client/src/main/resources/resource-handler.vm index 837604d84ed..f0183ffd0f0 100644 --- a/extensions/chaosmesh/client/src/main/resources/resource-handler.vm +++ b/extensions/chaosmesh/client/src/main/resources/resource-handler.vm @@ -29,25 +29,15 @@ package io.fabric8.chaosmesh.client.handlers; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.chaosmesh.client.internal.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -64,53 +54,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/extensions/knative/client/src/main/resources/resource-handler.vm b/extensions/knative/client/src/main/resources/resource-handler.vm index b9700af8bdb..476417a5ed9 100644 --- a/extensions/knative/client/src/main/resources/resource-handler.vm +++ b/extensions/knative/client/src/main/resources/resource-handler.vm @@ -30,25 +30,16 @@ package io.fabric8.knative.client.${group}.${apiVersion}.handlers; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.knative.client.${group}.${apiVersion}.internal.${model.name}OperationsImpl; -import io.fabric8.kubernetes.client.dsl.base.OperationContext; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -65,53 +56,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } - - @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - + @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/extensions/service-catalog/client/src/main/resources/resource-handler.vm b/extensions/service-catalog/client/src/main/resources/resource-handler.vm index af3f38471fd..4426ff6b7c9 100644 --- a/extensions/service-catalog/client/src/main/resources/resource-handler.vm +++ b/extensions/service-catalog/client/src/main/resources/resource-handler.vm @@ -29,25 +29,15 @@ package io.fabric8.servicecatalog.client.handlers; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.servicecatalog.client.internal.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -64,53 +54,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/extensions/tekton/client/src/main/resources/resource-handler.vm b/extensions/tekton/client/src/main/resources/resource-handler.vm index 140478ed6e6..298219d0f4b 100644 --- a/extensions/tekton/client/src/main/resources/resource-handler.vm +++ b/extensions/tekton/client/src/main/resources/resource-handler.vm @@ -29,25 +29,15 @@ package io.fabric8.tekton.client.handlers.$apiVersion; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.tekton.client.internal.$apiVersion.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -64,53 +54,13 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } - - @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - + @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } } diff --git a/extensions/volumesnapshot/client/src/main/resources/resource-handler.vm b/extensions/volumesnapshot/client/src/main/resources/resource-handler.vm index f4d492320c7..826f145dc81 100644 --- a/extensions/volumesnapshot/client/src/main/resources/resource-handler.vm +++ b/extensions/volumesnapshot/client/src/main/resources/resource-handler.vm @@ -29,25 +29,15 @@ package io.fabric8.volumesnapshot.client.handlers; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.volumesnapshot.client.internal.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -64,53 +54,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions listOptions, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(listOptions, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/ResourceHandler.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/ResourceHandler.java index fd5a454a6a0..fd9a698aaeb 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/ResourceHandler.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/ResourceHandler.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.api.model.ListOptions; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; import io.fabric8.kubernetes.api.builder.VisitableBuilder; @@ -86,7 +87,9 @@ public boolean equals(Object obj) { * @param dryRun Enable dry run * @return The created resource. */ - T create(OkHttpClient client, Config config, String namespace, T item, boolean dryRun); + default T create(OkHttpClient client, Config config, String namespace, T item, boolean dryRun) { + return resource(client, config, namespace, item).dryRun(dryRun).create(item); + } /** * Replace the specified resource @@ -97,7 +100,9 @@ public boolean equals(Object obj) { * @param dryRun Enable dry run * @return The replaced resource. */ - T replace(OkHttpClient client, Config config, String namespace, T item, boolean dryRun); + default T replace(OkHttpClient client, Config config, String namespace, T item, boolean dryRun) { + return resource(client, config, namespace, item).dryRun(dryRun).replace(item); + } /** * Reload the specified resource (if exists). @@ -107,7 +112,9 @@ public boolean equals(Object obj) { * @param item The resource to reload. * @return The reloaded resource. */ - T reload(OkHttpClient client, Config config, String namespace, T item); + default T reload(OkHttpClient client, Config config, String namespace, T item) { + return resource(client, config, namespace, item).fromServer().get(); + } /** * Edit the specified resource. @@ -127,7 +134,9 @@ public boolean equals(Object obj) { * @param dryRun enable dry run * @return The true if the resource was successfully deleted. */ - Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, T item, boolean dryRun); + default Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, T item, boolean dryRun) { + return resource(client, config, namespace, item).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); + } /** @@ -139,8 +148,9 @@ public boolean equals(Object obj) { * @param watcher The {@link Watcher} to use. * @return The {@link Watch} */ - Watch watch(OkHttpClient client, Config config, String namespace, T item, Watcher watcher); - + default Watch watch(OkHttpClient client, Config config, String namespace, T item, Watcher watcher) { + return resource(client, config, namespace, item).watch(watcher); + } /** * Watches the specified resource for changes. @@ -152,7 +162,9 @@ public boolean equals(Object obj) { * @param watcher The {@link Watcher} to use. * @return The {@link Watch} */ - Watch watch(OkHttpClient client, Config config, String namespace, T item, String resourceVersion, Watcher watcher); + default Watch watch(OkHttpClient client, Config config, String namespace, T item, String resourceVersion, Watcher watcher) { + return resource(client, config, namespace, item).watch(resourceVersion, watcher); + } /** * Watches the specified resource for changes @@ -165,7 +177,9 @@ public boolean equals(Object obj) { * @param watcher The {@link Watcher} to use. * @return The {@link Watch} */ - Watch watch(OkHttpClient client, Config config, String namespace, T item, ListOptions listOptions, Watcher watcher); + default Watch watch(OkHttpClient client, Config config, String namespace, T item, ListOptions listOptions, Watcher watcher) { + return resource(client, config, namespace, item).watch(listOptions, watcher); + } /** * Waits until the specified resource is Ready. @@ -179,7 +193,13 @@ public boolean equals(Object obj) { * @return The true if the resource was successfully deleted. * @throws InterruptedException Interrupted Exception */ - T waitUntilReady(OkHttpClient client, Config config, String namespace, T item, long amount, TimeUnit timeUnit) throws InterruptedException; + default T waitUntilReady(OkHttpClient client, Config config, String namespace, T item, long amount, TimeUnit timeUnit) { + return resource(client, config, namespace, item).waitUntilReady(amount, timeUnit); + } + + default T waitUntilCondition(OkHttpClient client, Config config, String namespace, T item, Predicate condition, long amount, TimeUnit timeUnit) { + return resource(client, config, namespace, item).waitUntilCondition(condition, amount, timeUnit); + } - T waitUntilCondition(OkHttpClient client, Config config, String namespace, T item, Predicate condition, long amount, TimeUnit timeUnit) throws InterruptedException; + Resource resource(OkHttpClient client, Config config, String namespace, T item); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/Waitable.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/Waitable.java index ef331895ee8..aa6abf25204 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/Waitable.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/Waitable.java @@ -15,6 +15,7 @@ */ package io.fabric8.kubernetes.client.dsl; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @@ -34,6 +35,10 @@ public interface Waitable { T waitUntilReady(long amount, TimeUnit timeUnit); T waitUntilCondition(Predicate

condition, long amount, TimeUnit timeUnit); + + CompletableFuture ready(); + + CompletableFuture condition(Predicate

condition); /** * Configure the backoff strategy to use when waiting for conditions, in case the watcher encounters a retryable error. diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/WatchListDeletable.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/WatchListDeletable.java index 9a7259542fc..b41b9e2048d 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/WatchListDeletable.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/WatchListDeletable.java @@ -17,11 +17,22 @@ import io.fabric8.kubernetes.client.GracePeriodConfigurable; import io.fabric8.kubernetes.client.PropagationPolicyConfigurable; +import io.fabric8.kubernetes.client.Watcher; -public interface WatchListDeletable extends VersionWatchAndWaitable, Listable, Deletable, +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; + +public interface WatchListDeletable extends Watchable>, Versionable>, Listable, Deletable, GracePeriodConfigurable, PropagationPolicyConfigurable>, StatusUpdatable, Informable { + + List waitUntilListCondition(Predicate> condition, long amount, TimeUnit timeUnit); + + CompletableFuture> listCondition(Predicate> condition); + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/BaseOperation.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/BaseOperation.java index e660a0e087c..25a9faa68fc 100755 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/BaseOperation.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/BaseOperation.java @@ -18,8 +18,6 @@ import io.fabric8.kubernetes.api.model.ObjectReference; import io.fabric8.kubernetes.client.dsl.WritableOperation; import io.fabric8.kubernetes.client.utils.CreateOrReplaceHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import io.fabric8.kubernetes.api.builder.TypedVisitor; import io.fabric8.kubernetes.api.builder.Visitor; @@ -78,7 +76,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -94,7 +92,6 @@ public class BaseOperation, Resource { - private static final Logger LOG = LoggerFactory.getLogger(BaseOperation.class); private static final String READ_ONLY_UPDATE_EXCEPTION_MESSAGE = "Cannot update read-only resources"; private static final String READ_ONLY_EDIT_EXCEPTION_MESSAGE = "Cannot edit read-only resources"; @@ -972,61 +969,94 @@ public final Boolean isReady() { @Override public T waitUntilReady(long amount, TimeUnit timeUnit) { - return waitUntilCondition(resource -> Objects.nonNull(resource) && getReadiness().isReady(resource), amount, timeUnit); + return waitUntilCondition(readyPredicate(), amount, timeUnit); + } + + @Override + public CompletableFuture ready() { + return condition(readyPredicate()); } + private Predicate readyPredicate() { + return resource -> Objects.nonNull(resource) && getReadiness().isReady(resource); + } + @Override public T waitUntilCondition(Predicate condition, long amount, TimeUnit timeUnit) { - CompletableFuture future = new CompletableFuture<>(); - // tests the condition, trapping any exceptions - Consumer tester = obj -> { - try { - if (condition.test(obj)) { - future.complete(obj); - } - } catch (Exception e) { - future.completeExceptionally(e); + CompletableFuture futureCondition = condition(condition); + if (!Utils.waitUntilReady(futureCondition, amount, timeUnit, true)) { + T i = getItem(); + if (i != null) { + throw new KubernetesClientTimeoutException(i, amount, timeUnit); + } + throw new KubernetesClientTimeoutException(getKind(), getName(), getNamespace(), amount, timeUnit); + } + return futureCondition.getNow(null); + } + + @Override + public CompletableFuture condition(Predicate condition) { + return listCondition(l -> { + if (l.isEmpty()) { + return condition.test(null); } - }; + return condition.test(l.get(0)); + }).thenApply(l -> l.isEmpty() ? null : l.get(0)); + } + + @Override + public List waitUntilListCondition(Predicate> condition, long amount, TimeUnit timeUnit) { + CompletableFuture> listCondition = listCondition(condition); + if (!Utils.waitUntilReady(listCondition, amount, timeUnit, true)) { + // it would be good to report the last state of the cache here + throw new KubernetesClientTimeoutException(getKind(), getName(), getNamespace(), amount, timeUnit); + } + return listCondition.getNow(null); + } + + @Override + public CompletableFuture> listCondition(Predicate> condition) { + CompletableFuture> future = new CompletableFuture<>(); + // tests the condition, trapping any exceptions + AtomicReference tester = new AtomicReference<>(); // start an informer that supplies the tester with events and empty list handling - try (SharedIndexInformer informer = this.createInformer(0, l -> { + SharedIndexInformer informer = this.createInformer(0, l -> { if (l.getItems().isEmpty()) { - tester.accept(null); + tester.get().run(); } }, new ResourceEventHandler() { - + @Override public void onAdd(T obj) { - tester.accept(obj); + tester.get().run(); } @Override public void onUpdate(T oldObj, T newObj) { - tester.accept(newObj); + tester.get().run(); } @Override public void onDelete(T obj, boolean deletedFinalStateUnknown) { - tester.accept(null); + tester.get().run(); } - })) { - // prevent unnecessary watches - future.whenComplete((r,t) -> informer.stop()); - informer.run(); - return future.get(amount, timeUnit); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw KubernetesClientException.launderThrowable(e.getCause()); - } catch (ExecutionException e) { - throw KubernetesClientException.launderThrowable(e.getCause()); - } catch (TimeoutException e) { - T i = getItem(); - if (i != null) { - throw new KubernetesClientTimeoutException(i, amount, timeUnit); + }); + // prevent unnecessary watches and handle closure + future.whenComplete((r,t) -> informer.stop()); + // use the cache to evaluate the list predicate + tester.set(() -> { + try { + List list = informer.getStore().list(); + if (condition.test(list)) { + future.complete(list); + } + } catch (Exception e) { + future.completeExceptionally(e); } - throw new KubernetesClientTimeoutException(getKind(), getName(), getNamespace(), amount, timeUnit); - } - } + }); + informer.run(); + return future; + } public void setType(Class type) { this.type = type; @@ -1064,7 +1094,7 @@ public SharedIndexInformer inform(ResourceEventHandler handler, long resyn private DefaultSharedIndexInformer createInformer(long resync, Consumer onList, ResourceEventHandler handler) { T i = getItem(); String name = (Utils.isNotNullOrEmpty(getName()) || i != null) ? checkName(i) : null; - + // use the local context / namespace DefaultSharedIndexInformer informer = new DefaultSharedIndexInformer<>(getType(), new ListerWatcher() { @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LogWatchCallback.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LogWatchCallback.java index ccddd1926ce..9898e01a907 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LogWatchCallback.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/LogWatchCallback.java @@ -107,7 +107,7 @@ private void cleanUp() { } public void waitUntilReady() { - if (!Utils.waitUntilReady(startedFuture, config.getRequestTimeout(), TimeUnit.MILLISECONDS)) { + if (!Utils.waitUntilReady(startedFuture, config.getRequestTimeout(), TimeUnit.MILLISECONDS, true)) { if (LOGGER.isDebugEnabled()) { LOGGER.warn("Log watch request has not been opened within: " + config.getRequestTimeout() + " millis."); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl.java index 273a6c31ba4..81bcb353e4f 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl.java @@ -20,6 +20,7 @@ import io.fabric8.kubernetes.client.dsl.VisitFromServerWritable; import io.fabric8.kubernetes.client.utils.Utils; +import java.util.function.Function; import java.util.function.Predicate; import java.io.ByteArrayInputStream; @@ -28,6 +29,7 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import io.fabric8.kubernetes.api.builder.TypedVisitor; @@ -35,7 +37,6 @@ import io.fabric8.kubernetes.api.builder.Visitor; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.KubernetesList; -import io.fabric8.kubernetes.api.model.KubernetesResource; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.Handlers; @@ -49,10 +50,10 @@ import io.fabric8.kubernetes.client.dsl.Gettable; import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.Readiable; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.VisitFromServerGetWatchDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.Waitable; import io.fabric8.kubernetes.client.dsl.base.OperationSupport; -import io.fabric8.kubernetes.client.handlers.KubernetesListHandler; import io.fabric8.kubernetes.client.internal.readiness.Readiness; import okhttp3.OkHttpClient; @@ -253,12 +254,7 @@ public final Boolean isReady() { public HasMetadata waitUntilReady(long amount, TimeUnit timeUnit) { HasMetadata meta = acceptVisitors(asHasMetadata(get()), visitors); ResourceHandler h = handlerOf(meta); - try { - return h.waitUntilReady(client, config, meta.getMetadata().getNamespace(), meta, amount, timeUnit); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw KubernetesClientException.launderThrowable(e); - } + return h.waitUntilReady(client, config, meta.getMetadata().getNamespace(), meta, amount, timeUnit); } @Override @@ -271,12 +267,7 @@ public HasMetadata waitUntilCondition(Predicate condition, long amo TimeUnit timeUnit) { HasMetadata meta = acceptVisitors(asHasMetadata(get()), visitors); ResourceHandler h = handlerOf(meta); - try { - return h.waitUntilCondition(client, config, meta.getMetadata().getNamespace(), meta, condition, amount, timeUnit); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw KubernetesClientException.launderThrowable(e); - } + return h.waitUntilCondition(client, config, meta.getMetadata().getNamespace(), meta, condition, amount, timeUnit); } @@ -304,12 +295,10 @@ private static HasMetadata asHasMetadata(T item) { throw new IllegalArgumentException("Item needs to be an instance of HasMetadata or String."); } - static ResourceHandler checkForHandlerOf(T item) { + static void checkForHandlerOf(T item) { if (item instanceof HasMetadata) { - return handlerOf((HasMetadata)item); - } else if (item instanceof KubernetesList) { - return new KubernetesListHandler(); - } else { + handlerOf((HasMetadata)item); + } else if (!(item instanceof KubernetesList)) { throw new IllegalArgumentException("Could not find a registered handler for item: [" + item + "]."); } } @@ -317,4 +306,20 @@ private static HasMetadata asHasMetadata(T item) { static ResourceHandler handlerOf(T item) { return Handlers.get(item.getKind(), item.getApiVersion()); } + + R onResource(Function, R> function) { + HasMetadata meta = acceptVisitors(asHasMetadata(item), visitors); + ResourceHandler h = handlerOf(meta); + return function.apply(h.resource(client, config, explicitNamespace, meta)); + } + + @Override + public CompletableFuture ready() { + return onResource(Resource::ready); + } + + @Override + public CompletableFuture condition(Predicate condition) { + return onResource(r -> r.condition(condition)); + } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java index d4a563bfb02..fc1ccb10e27 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java @@ -45,16 +45,15 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.CompletionException; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; +import java.util.stream.Collectors; import static io.fabric8.kubernetes.client.utils.CreateOrReplaceHelper.createOrReplaceItem; import static io.fabric8.kubernetes.client.utils.DeleteAndCreateHelper.deleteAndCreateItem; @@ -84,7 +83,47 @@ public class NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImp @Override public List waitUntilReady(final long amount, final TimeUnit timeUnit) { - return waitUntilCondition(resource -> Objects.nonNull(resource) && getReadiness().isReady(resource), amount, timeUnit); + return waitUntilCondition(readyPredicate(), amount, timeUnit); + } + + private Predicate readyPredicate() { + return resource -> Objects.nonNull(resource) && getReadiness().isReady(resource); + } + + @Override + public CompletableFuture> ready() { + return condition(readyPredicate()); + } + + @Override + public CompletableFuture> condition(Predicate condition) { + final List> futures = + conditionFutures(acceptVisitors(asHasMetadata(item, true), visitors), condition); + return toCompletableFuture(futures); + } + + CompletableFuture> toCompletableFuture(final List> futures) { + CompletableFuture> result = + CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])) + .thenApply(v -> { + return futures.stream().map(f -> f.getNow(null)).collect(Collectors.toList()); + }); + result.whenComplete((v, t) -> futures.forEach(f -> f.cancel(true))); + return result; + } + + List> conditionFutures(List items, Predicate condition) { + final List> futures = new ArrayList<>(items.size()); + try { + for (final HasMetadata meta : items) { + final ResourceHandler h = handlerOf(meta); + futures.add(h.resource(client, config, explicitNamespace, meta).condition(condition)); + } + return futures; + } catch (RuntimeException e) { + futures.forEach(f -> f.cancel(true)); + throw e; + } } @Override @@ -92,57 +131,24 @@ public List waitUntilCondition(Predicate condition, long amount, TimeUnit timeUnit) { List items = acceptVisitors(asHasMetadata(item, true), visitors); - if (items.isEmpty()) { - return Collections.emptyList(); - } - // this strategy is very costly in terms of threads - by not exposing the underlying futures - // we have to create a thread for each item that mostly waits - final ExecutorService executor = Executors.newFixedThreadPool(items.size(), Utils.daemonThreadFactory(this)); - try { - final List> futures = new ArrayList<>(items.size()); - for (final HasMetadata meta : items) { - final ResourceHandler h = handlerOf(meta); - futures.add(CompletableFuture.supplyAsync(() -> { - try { - return h.waitUntilCondition(client, config, meta.getMetadata().getNamespace(), meta, condition, amount, timeUnit); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - }, executor)); - } - - final List results = new ArrayList<>(); - final List itemsWithConditionNotMatched = new ArrayList<>(); - - // Iterate over the items because we don't know what kind of List it is. - // But the futures use an ArrayList, so accessing by index is efficient. - int i = 0; - for (final HasMetadata meta : items) { + final List> futures = conditionFutures(items, condition); + CompletableFuture> completableFuture = toCompletableFuture(futures); + final List itemsWithConditionNotMatched = new ArrayList<>(); + if (!Utils.waitUntilReady(completableFuture, amount, timeUnit, true)) { + for (int i = 0; i < futures.size(); i++) { + HasMetadata meta = items.get(i); try { - CompletableFuture future = futures.get(i); - // just get each result as the timeout is enforced below - results.add(future.get()); - } catch (ExecutionException e) { + futures.get(i).getNow(null); + } catch (CancellationException | CompletionException e) { itemsWithConditionNotMatched.add(meta); - logAsNotReady(e.getCause(), meta); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw KubernetesClientException.launderThrowable(e); + logAsNotReady(e, meta); } - ++i; - } - - if (!itemsWithConditionNotMatched.isEmpty()) { - throw new KubernetesClientTimeoutException(itemsWithConditionNotMatched, amount, timeUnit); } - - return results; - } finally { - executor.shutdownNow(); + throw new KubernetesClientTimeoutException(itemsWithConditionNotMatched, amount, timeUnit); } + return completableFuture.getNow(null); } - + private static void logAsNotReady(Throwable t, HasMetadata meta) { LOGGER.warn("Error while waiting for: [{}] with name: [{}] in namespace: [{}]: {}. The resource will be considered not ready.", meta.getKind(), meta.getMetadata().getName(), meta.getMetadata().getNamespace(), t.getMessage()); LOGGER.debug("The error stack trace:", t); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentOperationsImpl.java index 8a5e657ba16..748fb932907 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentOperationsImpl.java @@ -27,13 +27,13 @@ import io.fabric8.kubernetes.client.dsl.base.PatchContext; import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; -import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; import io.fabric8.kubernetes.api.model.apps.DeploymentList; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,11 +47,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; @@ -262,24 +258,18 @@ public ImageEditReplacePatchable withTimeout(long timeout, TimeUnit * Lets wait until there are enough Ready pods of the given Deployment */ private void waitUntilDeploymentIsScaled(final int count) { - final CompletableFuture scaledFuture = new CompletableFuture<>(); final AtomicReference replicasRef = new AtomicReference<>(0); final String name = checkName(getItem()); final String namespace = checkNamespace(getItem()); - final Runnable deploymentPoller = () -> { - try { - Deployment deployment = get(); - //If the deployment is gone, we shouldn't wait. + try { + waitUntilCondition(deployment -> { if (deployment == null) { if (count == 0) { - scaledFuture.complete(null); - return; - } else { - scaledFuture.completeExceptionally(new IllegalStateException("Can't wait for Deployment: " + checkName(getItem()) + " in namespace: " + checkName(getItem()) + " to scale. Resource is no longer available.")); - return; + return true; } + throw new IllegalStateException("Can't wait for Deployment: " + checkName(getItem()) + " in namespace: " + checkName(getItem()) + " to scale. Resource is no longer available."); } replicasRef.set(deployment.getStatus().getReplicas()); @@ -287,29 +277,18 @@ private void waitUntilDeploymentIsScaled(final int count) { long generation = deployment.getMetadata().getGeneration() != null ? deployment.getMetadata().getGeneration() : 0; long observedGeneration = deployment.getStatus() != null && deployment.getStatus().getObservedGeneration() != null ? deployment.getStatus().getObservedGeneration() : -1; if (observedGeneration >= generation && Objects.equals(deployment.getSpec().getReplicas(), currentReplicas)) { - scaledFuture.complete(null); - } else { - LOG.debug("Only {}/{} pods scheduled for Deployment: {} in namespace: {} seconds so waiting...", - deployment.getStatus().getReplicas(), deployment.getSpec().getReplicas(), deployment.getMetadata().getName(), namespace); - } - } catch (Throwable t) { - LOG.error("Error while waiting for Deployment to be scaled.", t); - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(deploymentPoller, 0, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); - try { - if (Utils.waitUntilReady(scaledFuture, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS)) { - LOG.debug("{}/{} pod(s) ready for Deployment: {} in namespace: {}.", + return true; + } + LOG.debug("Only {}/{} pods scheduled for Deployment: {} in namespace: {} seconds so waiting...", + deployment.getStatus().getReplicas(), deployment.getSpec().getReplicas(), deployment.getMetadata().getName(), namespace); + return false; + + }, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); + LOG.debug("{}/{} pod(s) ready for Deployment: {} in namespace: {}.", replicasRef.get(), count, name, namespace); - } else { - LOG.error("{}/{} pod(s) ready for Deployment: {} in namespace: {} after waiting for {} seconds so giving up", + } catch (KubernetesClientTimeoutException e) { + LOG.error("{}/{} pod(s) ready for Deployment: {} in namespace: {} after waiting for {} seconds so giving up", replicasRef.get(), count, name, namespace, TimeUnit.MILLISECONDS.toSeconds(getConfig().getScaleTimeout())); - } - } finally { - poller.cancel(true); - executor.shutdown(); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentRollingUpdater.java index f4aa30037e8..c5e5e88efb1 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/DeploymentRollingUpdater.java @@ -16,6 +16,7 @@ package io.fabric8.kubernetes.client.dsl.internal.apps.v1; import okhttp3.OkHttpClient; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder; @@ -23,6 +24,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; class DeploymentRollingUpdater extends RollingUpdater { @@ -48,10 +50,10 @@ protected Deployment createClone(Deployment obj, String newName, String newDeplo .endSpec() .build(); } - + @Override - protected PodList listSelectedPods(Deployment obj) { - return listSelectedPods(obj.getSpec().getSelector()); + protected WatchListDeletable selectedPodLister(Deployment obj) { + return selectedPodLister(obj.getSpec().getSelector()); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetRollingUpdater.java index e1ddcfd14f1..2489aba2ddd 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetRollingUpdater.java @@ -15,6 +15,7 @@ */ package io.fabric8.kubernetes.client.dsl.internal.apps.v1; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.apps.ReplicaSet; import io.fabric8.kubernetes.api.model.apps.ReplicaSetBuilder; @@ -22,6 +23,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; import okhttp3.OkHttpClient; class ReplicaSetRollingUpdater extends RollingUpdater { @@ -50,8 +52,8 @@ protected ReplicaSet createClone(ReplicaSet obj, String newName, String newDeplo } @Override - protected PodList listSelectedPods(ReplicaSet obj) { - return listSelectedPods(obj.getSpec().getSelector()); + protected WatchListDeletable selectedPodLister(ReplicaSet obj) { + return selectedPodLister(obj.getSpec().getSelector()); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollableScalableResourceOperation.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollableScalableResourceOperation.java index 3e9b4a7e320..61532dbd2fe 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollableScalableResourceOperation.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollableScalableResourceOperation.java @@ -19,21 +19,17 @@ import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.api.model.autoscaling.v1.Scale; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; import io.fabric8.kubernetes.client.dsl.base.PatchContext; import io.fabric8.kubernetes.client.dsl.base.PatchType; import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; -import io.fabric8.kubernetes.client.utils.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; @@ -74,8 +70,10 @@ public T scale(int count) { public T scale(int count, boolean wait) { T res = withReplicas(count); if (wait) { - waitUntilScaled(count); - res = getMandatory(); + res = waitUntilScaled(count); + if (res == null) { + res = getMandatory(); + } } return res; } @@ -93,53 +91,37 @@ public Scale scale(Scale scaleParam) { /** * Let's wait until there are enough Ready pods. */ - private void waitUntilScaled(final int count) { - final CompletableFuture scaledFuture = new CompletableFuture<>(); + private T waitUntilScaled(final int count) { final AtomicReference replicasRef = new AtomicReference<>(0); final String name = checkName(getItem()); final String namespace = checkNamespace(getItem()); - final Runnable tPoller = () -> { - try { - T t = get(); - //If the resource is gone, we shouldn't wait. - if (t == null) { - if (count == 0) { - scaledFuture.complete(null); - } else { - scaledFuture.completeExceptionally(new IllegalStateException("Can't wait for " + getType().getSimpleName() + ": " +name + " in namespace: " + namespace + " to scale. Resource is no longer available.")); - } - return; - } - int currentReplicas = getCurrentReplicas(t); - int desiredReplicas = getDesiredReplicas(t); - replicasRef.set(currentReplicas); - long generation = t.getMetadata().getGeneration() != null ? t.getMetadata().getGeneration() : -1; - long observedGeneration = getObservedGeneration(t); - if (observedGeneration >= generation && Objects.equals(desiredReplicas, currentReplicas)) { - scaledFuture.complete(null); - } - Log.debug("Only {}/{} replicas scheduled for {}: {} in namespace: {} seconds so waiting...", - currentReplicas, desiredReplicas, t.getKind(), t.getMetadata().getName(), namespace); - } catch (Throwable t) { - Log.error("Error while waiting for resource to be scaled.", t); - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(tPoller, 0, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); try { - if (Utils.waitUntilReady(scaledFuture, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS)) { - Log.debug("{}/{} pod(s) ready for {}: {} in namespace: {}.", - replicasRef.get(), count, getType().getSimpleName(), name, namespace); - } else { - Log.error("{}/{} pod(s) ready for {}: {} in namespace: {} after waiting for {} seconds so giving up", + return waitUntilCondition(t -> { + //If the resource is gone, we shouldn't wait. + if (t == null) { + if (count == 0) { + return true; + } + new IllegalStateException("Can't wait for " + getType().getSimpleName() + ": " +name + " in namespace: " + namespace + " to scale. Resource is no longer available."); + } + int currentReplicas = getCurrentReplicas(t); + int desiredReplicas = getDesiredReplicas(t); + replicasRef.set(currentReplicas); + long generation = t.getMetadata().getGeneration() != null ? t.getMetadata().getGeneration() : -1; + long observedGeneration = getObservedGeneration(t); + if (observedGeneration >= generation && Objects.equals(desiredReplicas, currentReplicas)) { + return true; + } + Log.debug("Only {}/{} replicas scheduled for {}: {} in namespace: {} seconds so waiting...", + currentReplicas, desiredReplicas, t.getKind(), t.getMetadata().getName(), namespace); + return false; + }, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); + } catch (KubernetesClientTimeoutException e) { + Log.error("{}/{} pod(s) ready for {}: {} in namespace: {} after waiting for {} seconds so giving up", replicasRef.get(), count, getType().getSimpleName(), name, namespace, TimeUnit.MILLISECONDS.toSeconds(getConfig().getScaleTimeout())); - } - } finally { - poller.cancel(true); - executor.shutdown(); + return null; } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollingUpdater.java index dd97abb5660..800c2c81cde 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/RollingUpdater.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl; +import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.LabelSelector; @@ -26,9 +27,11 @@ import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.PodResource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,12 +42,8 @@ import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -80,7 +79,7 @@ public RollingUpdater(OkHttpClient client, Config config, String namespace, long protected abstract T createClone(T obj, String newName, String newDeploymentHash); - protected abstract PodList listSelectedPods(T obj); + protected abstract WatchListDeletable selectedPodLister(T obj); protected abstract T updateDeploymentKey(String name, String hash); @@ -101,7 +100,7 @@ public T rollUpdate(T oldObj, T newObj) { String oldDeploymentHash = md5sum(oldObj); //Before we update the resource though we need to add the labels to the existing managed pods - PodList oldPods = listSelectedPods(oldObj); + PodList oldPods = selectedPodLister(oldObj).list(); for (Pod pod : oldPods.getItems()) { try { @@ -207,40 +206,27 @@ public static Map requestPayLoadForRolloutRestart() { * Lets wait until there are enough Ready pods of the given RC */ private void waitUntilPodsAreReady(final T obj, final String namespace, final int requiredPodCount) { - final CountDownLatch countDownLatch = new CountDownLatch(1); final AtomicInteger podCount = new AtomicInteger(0); - - final Runnable readyPodsPoller = () -> { - PodList podList = listSelectedPods(obj); - int count = 0; - List items = podList.getItems(); - for (Pod item : items) { - for (PodCondition c : item.getStatus().getConditions()) { - if (c.getType().equals("Ready") && c.getStatus().equals("True")) { - count++; + + ScheduledFuture logger = Utils.scheduleAtFixedRate(Utils.getCommonExecutorSerive(), + () -> LOG.debug("Only {}/{} pod(s) ready for {}: {} in namespace: {} seconds so waiting...", + podCount.get(), requiredPodCount, obj.getKind(), obj.getMetadata().getName(), namespace), + 0, loggingIntervalMillis, TimeUnit.MILLISECONDS); + try { + selectedPodLister(obj).waitUntilListCondition(items -> { + int count = 0; + for (Pod item : items) { + for (PodCondition c : item.getStatus().getConditions()) { + if (c.getType().equals("Ready") && c.getStatus().equals("True")) { + count++; + } } } - } - podCount.set(count); - if (count == requiredPodCount) { - countDownLatch.countDown(); - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(readyPodsPoller, 0, 1, TimeUnit.SECONDS); - ScheduledFuture logger = executor.scheduleWithFixedDelay(() -> LOG.debug("Only {}/{} pod(s) ready for {}: {} in namespace: {} seconds so waiting...", - podCount.get(), requiredPodCount, obj.getKind(), obj.getMetadata().getName(), namespace), 0, loggingIntervalMillis, TimeUnit.MILLISECONDS); - try { - countDownLatch.await(rollingTimeoutMillis, TimeUnit.MILLISECONDS); - executor.shutdown(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - poller.cancel(true); - logger.cancel(true); - executor.shutdown(); - LOG.warn("Only {}/{} pod(s) ready for {}: {} in namespace: {} after waiting for {} seconds so giving up", - podCount.get(), requiredPodCount, obj.getKind(), obj.getMetadata().getName(), namespace, TimeUnit.MILLISECONDS.toSeconds(rollingTimeoutMillis)); + podCount.set(count); + return count == requiredPodCount; + }, rollingTimeoutMillis, TimeUnit.MILLISECONDS); + } finally { + logger.cancel(true); // since we're using the common pool, we must shutdown manually } } @@ -249,34 +235,15 @@ private void waitUntilPodsAreReady(final T obj, final String namespace, final in * Lets wait until the resource is actually deleted in the server */ private void waitUntilDeleted(final String namespace, final String name) { - final CountDownLatch countDownLatch = new CountDownLatch(1); - - final Runnable waitTillDeletedPoller = () -> { - try { - T res = resources().inNamespace(namespace).withName(name).get(); - if (res == null) { - countDownLatch.countDown(); - } - } catch (KubernetesClientException e) { - if (e.getCode() == 404) { - countDownLatch.countDown(); - } - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(waitTillDeletedPoller, 0, 5, TimeUnit.SECONDS); - ScheduledFuture logger = executor.scheduleWithFixedDelay(() -> LOG.debug("Found resource {}/{} not yet deleted on server, so waiting...", namespace, name), 0, loggingIntervalMillis, TimeUnit.MILLISECONDS); + ScheduledFuture logger = Utils.scheduleAtFixedRate(Utils.getCommonExecutorSerive(), + () -> LOG.debug("Found resource {}/{} not yet deleted on server, so waiting...", namespace, name), + 0, loggingIntervalMillis, TimeUnit.MILLISECONDS); try { - countDownLatch.await(DEFAULT_SERVER_GC_WAIT_TIMEOUT, TimeUnit.MILLISECONDS); - executor.shutdown(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - poller.cancel(true); - logger.cancel(true); - executor.shutdown(); - LOG.warn("Still found deleted resource {} in namespace: {} after waiting for {} seconds so giving up", - name, namespace, TimeUnit.MILLISECONDS.toSeconds(DEFAULT_SERVER_GC_WAIT_TIMEOUT)); + resources().inNamespace(namespace) + .withName(name) + .waitUntilCondition(Objects::isNull, DEFAULT_SERVER_GC_WAIT_TIMEOUT, TimeUnit.MILLISECONDS); + } finally { + logger.cancel(true); // since we're using the common pool, we must shutdown manually } } @@ -292,8 +259,8 @@ protected Operation> pods() { return new PodOperationsImpl(client, config); } - protected PodList listSelectedPods(LabelSelector selector) { - return pods().inNamespace(namespace).withLabelSelector(selector).list(); + protected FilterWatchListDeletable selectedPodLister(LabelSelector selector) { + return pods().inNamespace(namespace).withLabelSelector(selector); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetRollingUpdater.java index 4614fadec97..8ba93f440a3 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetRollingUpdater.java @@ -15,6 +15,7 @@ */ package io.fabric8.kubernetes.client.dsl.internal.apps.v1; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.apps.StatefulSet; import io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder; @@ -22,6 +23,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; import okhttp3.OkHttpClient; class StatefulSetRollingUpdater extends RollingUpdater { @@ -50,8 +52,8 @@ protected StatefulSet createClone(StatefulSet obj, String newName, String newDep } @Override - protected PodList listSelectedPods(StatefulSet obj) { - return listSelectedPods(obj.getSpec().getSelector()); + protected WatchListDeletable selectedPodLister(StatefulSet obj) { + return selectedPodLister(obj.getSpec().getSelector()); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/batch/v1/JobOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/batch/v1/JobOperationsImpl.java index d813d551ca1..86a70664c9e 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/batch/v1/JobOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/batch/v1/JobOperationsImpl.java @@ -41,10 +41,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -125,41 +121,21 @@ public Job scale(int count, boolean wait) { * Lets wait until there are enough Ready pods of the given Job */ private void waitUntilJobIsScaled() { - final CountDownLatch countDownLatch = new CountDownLatch(1); - final AtomicReference atomicJob = new AtomicReference<>(); - final Runnable jobPoller = () -> { - try { - Job job = getMandatory(); - atomicJob.set(job); - Integer activeJobs = job.getStatus().getActive(); - if (activeJobs == null) { - activeJobs = 0; - } - if (Objects.equals(job.getSpec().getParallelism(), activeJobs)) { - countDownLatch.countDown(); - } else { - LOG.debug("Only {}/{} pods scheduled for Job: {} in namespace: {} seconds so waiting...", - job.getStatus().getActive(), job.getSpec().getParallelism(), job.getMetadata().getName(), namespace); - } - } catch (Throwable t) { - LOG.error("Error while waiting for Job to be scaled.", t); + waitUntilCondition(job -> { + atomicJob.set(job); + Integer activeJobs = job.getStatus().getActive(); + if (activeJobs == null) { + activeJobs = 0; } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(jobPoller, 0, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); - try { - countDownLatch.await(getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); - executor.shutdown(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - poller.cancel(true); - executor.shutdown(); - LOG.error("Only {}/{} pod(s) ready for Job: {} in namespace: {} - giving up", - atomicJob.get().getStatus().getActive(), atomicJob.get().getSpec().getParallelism(), atomicJob.get().getMetadata().getName(), namespace); - } + if (Objects.equals(job.getSpec().getParallelism(), activeJobs)) { + return true; + } + LOG.debug("Only {}/{} pods scheduled for Job: {} in namespace: {} seconds so waiting...", + job.getStatus().getActive(), job.getSpec().getParallelism(), job.getMetadata().getName(), namespace); + return false; + }, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); } public String getLog() { diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerRollingUpdater.java index 5f40ff827f2..6c99df91b00 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerRollingUpdater.java @@ -17,6 +17,7 @@ import io.fabric8.kubernetes.client.dsl.internal.apps.v1.RollingUpdater; import okhttp3.OkHttpClient; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.ReplicationController; import io.fabric8.kubernetes.api.model.ReplicationControllerBuilder; @@ -24,6 +25,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; class ReplicationControllerRollingUpdater extends RollingUpdater { @@ -48,10 +50,10 @@ protected ReplicationController createClone(ReplicationController obj, String ne .endSpec() .build(); } - + @Override - protected PodList listSelectedPods(ReplicationController obj) { - return pods().inNamespace(namespace).withLabels(obj.getSpec().getSelector()).list(); + protected WatchListDeletable selectedPodLister(ReplicationController obj) { + return pods().inNamespace(namespace).withLabels(obj.getSpec().getSelector()); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentOperationsImpl.java index 5f393356194..78bde23d1f6 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentOperationsImpl.java @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.api.model.extensions.ReplicaSetList; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; import io.fabric8.kubernetes.client.dsl.ImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.LogWatch; import io.fabric8.kubernetes.client.dsl.Loggable; @@ -38,7 +39,6 @@ import io.fabric8.kubernetes.client.dsl.internal.apps.v1.RollableScalableResourceOperation; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.RollingUpdater; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; -import io.fabric8.kubernetes.client.utils.Utils; import okhttp3.OkHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,11 +53,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; @@ -268,24 +264,19 @@ public ImageEditReplacePatchable withTimeout(long timeout, TimeUnit * Lets wait until there are enough Ready pods of the given Deployment */ private void waitUntilDeploymentIsScaled(final int count) { - final CompletableFuture scaledFuture = new CompletableFuture<>(); final AtomicReference replicasRef = new AtomicReference<>(0); final String name = checkName(getItem()); final String namespace = checkNamespace(getItem()); - final Runnable deploymentPoller = () -> { - try { - Deployment deployment = get(); - //If the deployment is gone, we shouldn't wait. + try { + waitUntilCondition(deployment -> { + // If the deployment is gone, we shouldn't wait. if (deployment == null) { if (count == 0) { - scaledFuture.complete(null); - return; - } else { - scaledFuture.completeExceptionally(new IllegalStateException("Can't wait for Deployment: " + checkName(getItem()) + " in namespace: " + checkName(getItem()) + " to scale. Resource is no longer available.")); - return; - } + return true; + } + throw new IllegalStateException("Can't wait for Deployment: " + checkName(getItem()) + " in namespace: " + checkName(getItem()) + " to scale. Resource is no longer available."); } replicasRef.set(deployment.getStatus().getReplicas()); @@ -293,29 +284,17 @@ private void waitUntilDeploymentIsScaled(final int count) { long generation = deployment.getMetadata().getGeneration() != null ? deployment.getMetadata().getGeneration() : 0; long observedGeneration = deployment.getStatus() != null && deployment.getStatus().getObservedGeneration() != null ? deployment.getStatus().getObservedGeneration() : -1; if (observedGeneration >= generation && Objects.equals(deployment.getSpec().getReplicas(), currentReplicas)) { - scaledFuture.complete(null); - } else { - LOG.debug("Only {}/{} pods scheduled for Deployment: {} in namespace: {} seconds so waiting...", - deployment.getStatus().getReplicas(), deployment.getSpec().getReplicas(), deployment.getMetadata().getName(), namespace); + return true; } - } catch (Exception t) { - LOG.error("Error while waiting for Deployment to be scaled.", t); - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(deploymentPoller, 0, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); - try { - if (Utils.waitUntilReady(scaledFuture, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS)) { - LOG.debug("{}/{} pod(s) ready for Deployment: {} in namespace: {}.", + LOG.debug("Only {}/{} pods scheduled for Deployment: {} in namespace: {} seconds so waiting...", + deployment.getStatus().getReplicas(), deployment.getSpec().getReplicas(), deployment.getMetadata().getName(), namespace); + return false; + }, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); + LOG.debug("{}/{} pod(s) ready for Deployment: {} in namespace: {}.", replicasRef.get(), count, name, namespace); - } else { - LOG.error("{}/{} pod(s) ready for Deployment: {} in namespace: {} after waiting for {} seconds so giving up", + } catch (KubernetesClientTimeoutException e) { + LOG.error("{}/{} pod(s) ready for Deployment: {} in namespace: {} after waiting for {} seconds so giving up", replicasRef.get(), count, name, namespace, TimeUnit.MILLISECONDS.toSeconds(getConfig().getScaleTimeout())); - } - } finally { - poller.cancel(true); - executor.shutdown(); } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentRollingUpdater.java index 5cd200c55ff..c7e95651634 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/DeploymentRollingUpdater.java @@ -15,6 +15,7 @@ */ package io.fabric8.kubernetes.client.dsl.internal.extensions.v1beta1; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.extensions.Deployment; import io.fabric8.kubernetes.api.model.extensions.DeploymentBuilder; @@ -22,6 +23,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.RollingUpdater; import okhttp3.OkHttpClient; @@ -51,9 +53,10 @@ protected Deployment createClone(Deployment obj, String newName, String newDeplo } @Override - protected PodList listSelectedPods(Deployment obj) { - return listSelectedPods(obj.getSpec().getSelector()); + protected WatchListDeletable selectedPodLister(Deployment obj) { + return selectedPodLister(obj.getSpec().getSelector()); } + @Override protected Deployment updateDeploymentKey(String name, String hash) { Deployment old = resources().inNamespace(namespace).withName(name).get(); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetRollingUpdater.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetRollingUpdater.java index 183911daaec..c5850e761ac 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetRollingUpdater.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetRollingUpdater.java @@ -15,6 +15,7 @@ */ package io.fabric8.kubernetes.client.dsl.internal.extensions.v1beta1; +import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.extensions.ReplicaSet; import io.fabric8.kubernetes.api.model.extensions.ReplicaSetBuilder; @@ -22,6 +23,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.dsl.Operation; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.WatchListDeletable; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.RollingUpdater; import okhttp3.OkHttpClient; @@ -51,8 +53,8 @@ protected ReplicaSet createClone(ReplicaSet obj, String newName, String newDeplo } @Override - protected PodList listSelectedPods(ReplicaSet obj) { - return listSelectedPods(obj.getSpec().getSelector()); + protected WatchListDeletable selectedPodLister(ReplicaSet obj) { + return selectedPodLister(obj.getSpec().getSelector()); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/KubernetesListHandler.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/KubernetesListHandler.java index 2d0fb82b51c..83c44827377 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/KubernetesListHandler.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/handlers/KubernetesListHandler.java @@ -27,6 +27,7 @@ import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.Handlers; import io.fabric8.kubernetes.client.ResourceHandler; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.internal.KubernetesListOperationsImpl; import org.apache.felix.scr.annotations.Component; import org.slf4j.Logger; @@ -118,12 +119,17 @@ public Watch watch(OkHttpClient client, Config config, String namespace, Kuberne } @Override - public KubernetesList waitUntilReady(OkHttpClient client, Config config, String namespace, KubernetesList item, long amount, TimeUnit timeUnit) throws InterruptedException { + public KubernetesList waitUntilReady(OkHttpClient client, Config config, String namespace, KubernetesList item, long amount, TimeUnit timeUnit) { throw new UnsupportedOperationException("Watch is not supported on KubernetesList."); } @Override - public KubernetesList waitUntilCondition(OkHttpClient client, Config config, String namespace, KubernetesList item, Predicate condition, long amount, TimeUnit timeUnit) throws InterruptedException { + public KubernetesList waitUntilCondition(OkHttpClient client, Config config, String namespace, KubernetesList item, Predicate condition, long amount, TimeUnit timeUnit) { throw new UnsupportedOperationException("Watch is not supported on KubernetesList."); } + + @Override + public Resource resource(OkHttpClient client, Config config, String namespace, KubernetesList item) { + throw new UnsupportedOperationException("Resource is not supported on KubernetesList."); + } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/CreateOrReplaceHelper.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/CreateOrReplaceHelper.java index bd549c845e0..ee01f4a47c9 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/CreateOrReplaceHelper.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/CreateOrReplaceHelper.java @@ -30,7 +30,6 @@ import java.util.function.UnaryOperator; public class CreateOrReplaceHelper { - private static final Logger LOG = LoggerFactory.getLogger(CreateOrReplaceHelper.class); public static final int CREATE_OR_REPLACE_RETRIES = 3; private final UnaryOperator createTask; private final UnaryOperator replaceTask; @@ -75,15 +74,7 @@ public static HasMetadata createOrReplaceItem(OkHttpClient client, Config config CreateOrReplaceHelper createOrReplaceHelper = new CreateOrReplaceHelper<>( m -> h.create(client, config, namespaceToUse, m, dryRun), m -> h.replace(client, config, namespaceToUse, m, dryRun), - m -> { - try { - return h.waitUntilCondition(client, config, namespaceToUse, m, Objects::nonNull, 1, TimeUnit.SECONDS); - } catch (InterruptedException interruptedException) { - Thread.currentThread().interrupt(); - LOG.warn("Interrupted waiting for item to be created or replaced. Gracefully assuming the resource hasn't been created and doesn't exist. ({})", interruptedException.getMessage()); - } - return null; - }, + m -> h.waitUntilCondition(client, config, namespaceToUse, m, Objects::nonNull, 1, TimeUnit.SECONDS), m -> h.reload(client, config, namespaceToUse, m) ); diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/DeleteAndCreateHelper.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/DeleteAndCreateHelper.java index 760208e5981..82b4392bded 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/DeleteAndCreateHelper.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/DeleteAndCreateHelper.java @@ -84,14 +84,6 @@ public static HasMetadata deleteAndCreateItem(OkHttpClient client, Config config } private static Function waitUntilDeletedOrInterrupted(OkHttpClient client, Config config, ResourceHandler h, String namespaceToUse) { - return m -> { - try { - return h.waitUntilCondition(client, config, namespaceToUse, m, Objects::isNull, MAX_WAIT_SECONDS , TimeUnit.SECONDS) == null; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - LOG.warn("interrupted waiting for item to be deleted, assuming not deleted"); - return false; - } - }; + return m -> h.waitUntilCondition(client, config, namespaceToUse, m, Objects::isNull, MAX_WAIT_SECONDS , TimeUnit.SECONDS) == null; } } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/Utils.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/Utils.java index 3acb87c655b..f2c9986e892 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/Utils.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/utils/Utils.java @@ -140,17 +140,18 @@ public static String join(final Object[] array, final char separator) { } return buf.toString(); } - + /** * Wait until an other thread signals the completion of a task. * If an exception is passed, it will be propagated to the caller. * @param future The communication channel. * @param amount The amount of time to wait. * @param timeUnit The time unit. + * @param cancel true if the future should be cancelled * * @return a boolean value indicating resource is ready or not. */ - public static boolean waitUntilReady(Future future, long amount, TimeUnit timeUnit) { + public static boolean waitUntilReady(Future future, long amount, TimeUnit timeUnit, boolean cancel) { try { future.get(amount, timeUnit); return true; @@ -165,14 +166,19 @@ public static boolean waitUntilReady(Future future, long amount, TimeUnit tim throw KubernetesClientException.launderThrowable(t); } catch (Exception e) { throw KubernetesClientException.launderThrowable(e); + } finally { + if (cancel) { + future.cancel(true); + } } } /** - * Similar to {@link #waitUntilReady(Future, long, TimeUnit)}, but will always throw an exception if not ready + * Similar to {@link #waitUntilReady(Future, long, TimeUnit, boolean)}, but will always throw an exception if not ready. + * The future will be canceled as a side-effect of this call. */ public static void waitUntilReadyOrFail(Future future, long amount, TimeUnit timeUnit) { - if (!waitUntilReady(future, amount, timeUnit)) { + if (!waitUntilReady(future, amount, timeUnit, true)) { throw new KubernetesClientException("not ready after " + amount + " " + timeUnit); } } diff --git a/kubernetes-client/src/main/resources/resource-handler.vm b/kubernetes-client/src/main/resources/resource-handler.vm index f962e02d8e8..aada09c349f 100644 --- a/kubernetes-client/src/main/resources/resource-handler.vm +++ b/kubernetes-client/src/main/resources/resource-handler.vm @@ -31,25 +31,15 @@ package io.fabric8.kubernetes.client.handlers$packageSuffix; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.internal$packageSuffix.${model.name}OperationsImpl; - -import io.fabric8.kubernetes.client.dsl.base.OperationContext; +import io.fabric8.kubernetes.client.dsl.Resource; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -66,53 +56,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, config, namespace).withItem(item).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } -@Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions options, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(options, watcher); - } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, config).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } } diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicaSetTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicaSetTest.java index c5b767d8ee3..721965eff2d 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicaSetTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicaSetTest.java @@ -17,6 +17,7 @@ package io.fabric8.kubernetes.client.mock; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.kubernetes.api.model.ListMetaBuilder; import io.fabric8.kubernetes.api.model.PodBuilder; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.PodListBuilder; @@ -28,7 +29,6 @@ import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.fabric8.kubernetes.client.utils.Utils; -import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -184,18 +184,27 @@ void testScaleAndWait() { .endStatus() .build()).once(); - server.expect().withPath("/apis/apps/v1/namespaces/test/replicasets/repl1").andReturn(200, new ReplicaSetBuilder() - .withNewMetadata() - .withName("repl1") - .withResourceVersion("1") - .endMetadata() - .withNewSpec() - .withReplicas(5) - .endSpec() - .withNewStatus() - .withReplicas(5) - .endStatus() - .build()).always(); + ReplicaSet scaled = new ReplicaSetBuilder() + .withNewMetadata() + .withName("repl1") + .withResourceVersion("1") + .endMetadata() + .withNewSpec() + .withReplicas(5) + .endSpec() + .withNewStatus() + .withReplicas(5) + .endStatus() + .build(); + // patch + server.expect().withPath("/apis/apps/v1/namespaces/test/replicasets/repl1").andReturn(200, scaled).once(); + + // list for waiting + server.expect() + .withPath("/apis/apps/v1/namespaces/test/replicasets?fieldSelector=metadata.name%3Drepl1&watch=false") + .andReturn(200, + new ReplicaSetListBuilder().withItems(scaled).withMetadata(new ListMetaBuilder().build()).build()) + .always(); ReplicaSet repl = client.apps().replicaSets().withName("repl1").scale(5, true); assertNotNull(repl); diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicationControllerTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicationControllerTest.java index 9d94abccab9..67bb6dc45ae 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicationControllerTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ReplicationControllerTest.java @@ -17,6 +17,7 @@ package io.fabric8.kubernetes.client.mock; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.kubernetes.api.model.ListMetaBuilder; import io.fabric8.kubernetes.api.model.PodBuilder; import io.fabric8.kubernetes.api.model.PodList; import io.fabric8.kubernetes.api.model.PodListBuilder; @@ -28,7 +29,6 @@ import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import io.fabric8.kubernetes.client.utils.Utils; -import okhttp3.mockwebserver.RecordedRequest; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -184,18 +184,26 @@ void testScaleAndWait() { .endStatus() .build()).once(); - server.expect().withPath("/api/v1/namespaces/test/replicationcontrollers/repl1").andReturn(200, new ReplicationControllerBuilder() - .withNewMetadata() - .withName("repl1") - .withResourceVersion("1") - .endMetadata() - .withNewSpec() - .withReplicas(5) - .endSpec() - .withNewStatus() - .withReplicas(5) - .endStatus() - .build()).always(); + ReplicationController scaled = new ReplicationControllerBuilder() + .withNewMetadata() + .withName("repl1") + .withResourceVersion("1") + .endMetadata() + .withNewSpec() + .withReplicas(5) + .endSpec() + .withNewStatus() + .withReplicas(5) + .endStatus() + .build(); + server.expect().withPath("/api/v1/namespaces/test/replicationcontrollers/repl1").andReturn(200, scaled).once(); + + // list for waiting + server.expect() + .withPath("/api/v1/namespaces/test/replicationcontrollers?fieldSelector=metadata.name%3Drepl1&watch=false") + .andReturn(200, + new ReplicationControllerListBuilder().withItems(scaled).withMetadata(new ListMetaBuilder().build()).build()) + .always(); ReplicationController repl = client.replicationControllers().withName("repl1").scale(5, true); assertNotNull(repl); diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceListTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceListTest.java index 76845069877..751aa9de2c5 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceListTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceListTest.java @@ -276,8 +276,8 @@ void testAllFailedWaitUntilCondition() { .anyMatch(c -> "True".equals(c.getStatus())); // The pods are never ready if you request them directly. - server.expect().get().withPath("/api/v1/namespaces/ns1/pods/pod1").andReturn(HTTP_OK, noReady1).once(); - server.expect().get().withPath("/api/v1/namespaces/ns1/pods/pod2").andReturn(HTTP_OK, noReady2).once(); + ResourceTest.list(server, noReady1); + ResourceTest.list(server, noReady2); Status gone = new StatusBuilder() .withCode(HTTP_GONE) diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceTest.java index 6a6acf1862a..a8a3792e9ce 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/ResourceTest.java @@ -246,7 +246,7 @@ static void list(KubernetesMockServer server, Pod pod) { .withPath("/api/v1/namespaces/"+pod.getMetadata().getNamespace()+"/pods?fieldSelector=metadata.name%3D"+pod.getMetadata().getName()+"&watch=false") .andReturn(200, new PodListBuilder().withItems(pod).withNewMetadata().withResourceVersion("1").endMetadata().build()) - .once(); + .always(); } @Test diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StatefulSetTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StatefulSetTest.java index 63f7627a577..49033d666c8 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StatefulSetTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/StatefulSetTest.java @@ -17,6 +17,7 @@ package io.fabric8.kubernetes.client.mock; import io.fabric8.kubernetes.api.model.KubernetesListBuilder; +import io.fabric8.kubernetes.api.model.ListMetaBuilder; import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder; import io.fabric8.kubernetes.api.model.Pod; import io.fabric8.kubernetes.api.model.PodBuilder; @@ -199,18 +200,26 @@ public void testScaleAndWait() { .endStatus() .build()).once(); - server.expect().withPath("/apis/apps/v1/namespaces/test/statefulsets/repl1").andReturn(200, new StatefulSetBuilder() - .withNewMetadata() - .withName("repl1") - .withResourceVersion("1") - .endMetadata() - .withNewSpec() - .withReplicas(5) - .endSpec() - .withNewStatus() - .withReplicas(5) - .endStatus() - .build()).always(); + StatefulSet scaled = new StatefulSetBuilder() + .withNewMetadata() + .withName("repl1") + .withResourceVersion("1") + .endMetadata() + .withNewSpec() + .withReplicas(5) + .endSpec() + .withNewStatus() + .withReplicas(5) + .endStatus() + .build(); + server.expect().withPath("/apis/apps/v1/namespaces/test/statefulsets/repl1").andReturn(200, scaled).once(); + + // list for waiting + server.expect() + .withPath("/apis/apps/v1/namespaces/test/statefulsets?fieldSelector=metadata.name%3Drepl1&watch=false") + .andReturn(200, + new StatefulSetListBuilder().withItems(scaled).withMetadata(new ListMetaBuilder().build()).build()) + .always(); StatefulSet repl = client.apps().statefulSets().withName("repl1").scale(5, true); assertNotNull(repl); diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/apps/DeploymentConfigOperationsImpl.java b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/apps/DeploymentConfigOperationsImpl.java index 687fe63b7b9..9073b919c25 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/apps/DeploymentConfigOperationsImpl.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/apps/DeploymentConfigOperationsImpl.java @@ -20,6 +20,7 @@ import io.fabric8.kubernetes.api.model.autoscaling.v1.Scale; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.KubernetesClientException; +import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; import io.fabric8.kubernetes.client.dsl.LogWatch; import io.fabric8.kubernetes.client.dsl.Loggable; import io.fabric8.kubernetes.client.dsl.PodResource; @@ -29,7 +30,6 @@ import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; import io.fabric8.kubernetes.client.utils.PodOperationUtil; import io.fabric8.kubernetes.client.utils.URLUtils; -import io.fabric8.kubernetes.client.utils.Utils; import io.fabric8.openshift.api.model.DeploymentConfig; import io.fabric8.openshift.api.model.DeploymentConfigBuilder; import io.fabric8.openshift.api.model.DeploymentConfigList; @@ -51,10 +51,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -172,52 +168,39 @@ public Scale scale(Scale scale) { * Lets wait until there are enough Ready pods of the given Deployment */ private void waitUntilDeploymentConfigIsScaled(final int count) { - final CompletableFuture scaledFuture = new CompletableFuture<>(); final AtomicReference replicasRef = new AtomicReference<>(0); final String name = checkName(getItem()); final String namespace = checkNamespace(getItem()); - final Runnable deploymentPoller = () -> { - try { - DeploymentConfig deploymentConfig = get(); + try { + waitUntilCondition(deploymentConfig -> { //If the rs is gone, we shouldn't wait. if (deploymentConfig == null) { if (count == 0) { - scaledFuture.complete(null); - return; - } else { - scaledFuture.completeExceptionally(new IllegalStateException("Can't wait for DeploymentConfig: " + checkName(getItem()) + " in namespace: " + checkName(getItem()) + " to scale. Resource is no longer available.")); - return; + return true; } + new IllegalStateException("Can't wait for DeploymentConfig: " + checkName(getItem()) + " in namespace: " + + checkName(getItem()) + " to scale. Resource is no longer available."); } replicasRef.set(deploymentConfig.getStatus().getReplicas()); int currentReplicas = deploymentConfig.getStatus().getReplicas() != null ? deploymentConfig.getStatus().getReplicas() : 0; - if (deploymentConfig.getStatus().getObservedGeneration() >= deploymentConfig.getMetadata().getGeneration() && Objects.equals(deploymentConfig.getSpec().getReplicas(), currentReplicas)) { - scaledFuture.complete(null); - } else { - LOG.debug("Only {}/{} pods scheduled for DeploymentConfig: {} in namespace: {} seconds so waiting...", - deploymentConfig.getStatus().getReplicas(), deploymentConfig.getSpec().getReplicas(), deploymentConfig.getMetadata().getName(), namespace); - } - } catch (Throwable t) { - LOG.error("Error while waiting for Deployment to be scaled.", t); - } - }; - - ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); - ScheduledFuture poller = executor.scheduleWithFixedDelay(deploymentPoller, 0, POLL_INTERVAL_MS, TimeUnit.MILLISECONDS); - try { - if (Utils.waitUntilReady(scaledFuture, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS)) { - LOG.debug("{}/{} pod(s) ready for DeploymentConfig: {} in namespace: {}.", - replicasRef.get(), count, name, namespace); - } else { - LOG.error("{}/{} pod(s) ready for DeploymentConfig: {} in namespace: {} after waiting for {} seconds so giving up", - replicasRef.get(), count, name, namespace, TimeUnit.MILLISECONDS.toSeconds(getConfig().getScaleTimeout())); + if (deploymentConfig.getStatus().getObservedGeneration() >= deploymentConfig.getMetadata().getGeneration() + && Objects.equals(deploymentConfig.getSpec().getReplicas(), currentReplicas)) { + return true; } - } finally { - poller.cancel(true); - executor.shutdown(); - } + LOG.debug("Only {}/{} pods scheduled for DeploymentConfig: {} in namespace: {} seconds so waiting...", + deploymentConfig.getStatus().getReplicas(), deploymentConfig.getSpec().getReplicas(), + deploymentConfig.getMetadata().getName(), namespace); + return false; + }, getConfig().getScaleTimeout(), TimeUnit.MILLISECONDS); + LOG.debug("{}/{} pod(s) ready for DeploymentConfig: {} in namespace: {}.", + replicasRef.get(), count, name, namespace); + } catch (KubernetesClientTimeoutException e) { + LOG.error("{}/{} pod(s) ready for DeploymentConfig: {} in namespace: {} after waiting for {} seconds so giving up", + replicasRef.get(), count, name, namespace, + TimeUnit.MILLISECONDS.toSeconds(getConfig().getScaleTimeout())); + } } @Override diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/ProjectRequestHandler.java b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/ProjectRequestHandler.java index f132974fdeb..c499e607625 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/ProjectRequestHandler.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/ProjectRequestHandler.java @@ -18,21 +18,21 @@ import io.fabric8.kubernetes.api.model.DeletionPropagation; import io.fabric8.kubernetes.api.model.ListOptions; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.ResourceHandler; import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; -import java.util.function.Predicate; - +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.base.OperationContext; -import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.ResourceHandler; import io.fabric8.openshift.api.model.ProjectRequest; import io.fabric8.openshift.api.model.ProjectRequestBuilder; import io.fabric8.openshift.client.dsl.internal.ProjectRequestsOperationImpl; +import okhttp3.OkHttpClient; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Service; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; @Component @Service @@ -88,12 +88,18 @@ public Watch watch(OkHttpClient client, Config config, String namespace, Project } @Override - public ProjectRequest waitUntilReady(OkHttpClient client, Config config, String namespace, ProjectRequest item, long amount, TimeUnit timeUnit) throws InterruptedException { + public ProjectRequest waitUntilReady(OkHttpClient client, Config config, String namespace, ProjectRequest item, long amount, TimeUnit timeUnit) { + throw new UnsupportedOperationException(); + } + + @Override + public ProjectRequest waitUntilCondition(OkHttpClient client, Config config, String namespace, ProjectRequest item, Predicate condition, long amount, TimeUnit timeUnit) { throw new UnsupportedOperationException(); } @Override - public ProjectRequest waitUntilCondition(OkHttpClient client, Config config, String namespace, ProjectRequest item, Predicate condition, long amount, TimeUnit timeUnit) throws InterruptedException { + public Resource resource(OkHttpClient client, Config config, String namespace, + ProjectRequest item) { throw new UnsupportedOperationException(); } } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/imageregistry/operator/ConfigHandler.java b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/imageregistry/operator/ConfigHandler.java index 5c20c1f65e8..f25447b144b 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/imageregistry/operator/ConfigHandler.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/imageregistry/operator/ConfigHandler.java @@ -15,20 +15,14 @@ */ package io.fabric8.openshift.client.handlers.imageregistry.operator; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config; import io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.ConfigBuilder; import io.fabric8.openshift.client.OpenShiftConfig; import io.fabric8.openshift.client.dsl.internal.imageregistry.operator.ConfigOperationsImpl; import okhttp3.OkHttpClient; -import java.util.concurrent.TimeUnit; -import java.util.function.Predicate; - public class ConfigHandler implements ResourceHandler { @Override @@ -41,54 +35,14 @@ public String getApiVersion() { return "imageregistry.operator.openshift.io/v1"; } - @Override - public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config create(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config replace(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config reload(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.ConfigBuilder edit(io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item) { return new io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.ConfigBuilder(item); } @Override - public Boolean delete(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, String resourceVersion, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, ListOptions options, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(options, watcher); - } - - - @Override - public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config waitUntilReady(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config waitUntilCondition(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.miscellaneous.imageregistry.operator.v1.Config item, Predicate condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); + public Resource resource(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, + Config item) { + return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/operator/ConfigHandler.java b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/operator/ConfigHandler.java index f36265e3993..1cd8503a715 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/operator/ConfigHandler.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/handlers/operator/ConfigHandler.java @@ -15,20 +15,13 @@ */ package io.fabric8.openshift.client.handlers.operator; -import java.util.function.Predicate; - -import io.fabric8.openshift.client.OpenShiftConfig; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.openshift.api.model.operator.v1.Config; +import io.fabric8.openshift.client.OpenShiftConfig; import io.fabric8.openshift.client.dsl.internal.operator.ConfigOperationsImpl; - import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; -import java.util.concurrent.TimeUnit; - public class ConfigHandler implements ResourceHandler { @Override @@ -41,54 +34,14 @@ public String getApiVersion() { return "operator.openshift.io/v1"; } - @Override - public io.fabric8.openshift.api.model.operator.v1.Config create(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public io.fabric8.openshift.api.model.operator.v1.Config replace(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public io.fabric8.openshift.api.model.operator.v1.Config reload(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public io.fabric8.openshift.api.model.operator.v1.ConfigBuilder edit(io.fabric8.openshift.api.model.operator.v1.Config item) { return new io.fabric8.openshift.api.model.operator.v1.ConfigBuilder(item); } @Override - public Boolean delete(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, io.fabric8.openshift.api.model.operator.v1.Config item, boolean dryRun) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, String resourceVersion, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, ListOptions options, Watcher watcher) { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(options, watcher); - } - - - @Override - public io.fabric8.openshift.api.model.operator.v1.Config waitUntilReady(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public io.fabric8.openshift.api.model.operator.v1.Config waitUntilCondition(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, io.fabric8.openshift.api.model.operator.v1.Config item, Predicate condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); + public Resource resource(OkHttpClient client, io.fabric8.kubernetes.client.Config config, String namespace, + Config item) { + return new ConfigOperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } } diff --git a/openshift-client/src/main/resources/resource-handler.vm b/openshift-client/src/main/resources/resource-handler.vm index 3f214e14aa0..3930b98416b 100644 --- a/openshift-client/src/main/resources/resource-handler.vm +++ b/openshift-client/src/main/resources/resource-handler.vm @@ -35,28 +35,20 @@ package io.fabric8.openshift.client.handlers.$packageSuffix; -import java.util.function.Predicate; - import io.fabric8.kubernetes.client.Config; import io.fabric8.openshift.client.OpenShiftConfig; import io.fabric8.kubernetes.client.ResourceHandler; -import io.fabric8.kubernetes.client.Watch; -import io.fabric8.kubernetes.client.Watcher; import io.fabric8.openshift.client.dsl.internal.$packageSuffix.${model.name}OperationsImpl; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.utils.ApiVersionUtil; import io.fabric8.openshift.client.OpenShiftConfig; import okhttp3.OkHttpClient; -import io.fabric8.kubernetes.api.model.DeletionPropagation; -import io.fabric8.kubernetes.api.model.ListOptions; import ${model.fullyQualifiedName}; import ${model.fullyQualifiedName}Builder; -import java.util.TreeMap; -import java.util.concurrent.TimeUnit; - public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> { @Override @@ -73,54 +65,14 @@ public class ${model.name}Handler implements ResourceHandler<${model.name}, ${mo #end } - @Override - public ${model.name} create(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).dryRun(dryRun).create(); - } - - @Override - public ${model.name} replace(OkHttpClient client, Config config, String namespace, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).dryRun(dryRun).replace(item); - } - - @Override - public ${model.name} reload(OkHttpClient client, Config config, String namespace, ${model.name} item) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).fromServer().get(); - } - @Override public ${model.name}Builder edit(${model.name} item) { return new ${model.name}Builder(item); } @Override - public Boolean delete(OkHttpClient client, Config config, String namespace, DeletionPropagation propagationPolicy, long gracePeriodSeconds, ${model.name} item, boolean dryRun) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).dryRun(dryRun).withPropagationPolicy(propagationPolicy).withGracePeriod(gracePeriodSeconds).delete(); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, String resourceVersion, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(resourceVersion, watcher); - } - - @Override - public Watch watch(OkHttpClient client, Config config, String namespace, ${model.name} item, ListOptions options, Watcher<${model.name}> watcher) { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).watch(options, watcher); + public Resource<${model.name}> resource(OkHttpClient client, Config config, String namespace, ${model.name} item) { + return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()); } - - @Override - public ${model.name} waitUntilReady(OkHttpClient client, Config config, String namespace, ${model.name} item, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilReady(amount, timeUnit); - } - - @Override - public ${model.name} waitUntilCondition(OkHttpClient client, Config config, String namespace, ${model.name} item, Predicate<${model.name}> condition, long amount, TimeUnit timeUnit) throws InterruptedException { - return new ${model.name}OperationsImpl(client, OpenShiftConfig.wrap(config)).withItem(item).inNamespace(namespace).withName(item.getMetadata().getName()).waitUntilCondition(condition, amount, timeUnit); - } }