From ddbac28ca7b79d945e690a71e340e6543a54d52e Mon Sep 17 00:00:00 2001 From: Steve Hawkins Date: Tue, 15 Nov 2022 13:11:02 -0500 Subject: [PATCH] fix #4516: adding a blocking delete operation --- doc/MIGRATION-v6.md | 3 +- .../client/dsl/DeletableWithOptions.java | 10 +- .../dsl/TimeoutImageEditReplacePatchable.java | 11 +- .../kubernetes/client/dsl/Timeoutable.java | 17 ++- .../client/extension/ExtensibleResource.java | 10 ++ .../extension/ExtensibleResourceAdapter.java | 11 ++ .../client/extension/ResourceAdapter.java | 11 ++ .../client/dsl/internal/BaseOperation.java | 16 +++ ...hDeleteRecreateWaitApplicableListImpl.java | 11 ++ .../client/dsl/internal/OperationContext.java | 28 ++++- .../dsl/internal/PodOperationContext.java | 2 + .../dsl/internal/RollingOperationContext.java | 112 ------------------ .../apps/v1/DeploymentOperationsImpl.java | 15 +-- .../apps/v1/ReplicaSetOperationsImpl.java | 13 +- .../v1/RollableScalableResourceOperation.java | 56 ++++----- .../apps/v1/StatefulSetOperationsImpl.java | 13 +- .../ReplicationControllerOperationsImpl.java | 13 +- .../v1beta1/DeploymentOperationsImpl.java | 14 +-- .../v1beta1/ReplicaSetOperationsImpl.java | 23 ++-- kubernetes-itests/pom.xml | 5 + .../java/io/fabric8/kubernetes/DeleteIT.java | 47 +++++++- .../client/mock/ResourceListTest.java | 4 +- .../client/dsl/TimeoutInputStreamable.java | 12 +- openshift-client/pom.xml | 5 + .../internal/BuildConfigOperationContext.java | 101 +++------------- .../apps/DeploymentConfigOperationsImpl.java | 19 ++- .../build/BuildConfigOperationsImpl.java | 16 +-- 27 files changed, 291 insertions(+), 307 deletions(-) delete mode 100644 kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/RollingOperationContext.java diff --git a/doc/MIGRATION-v6.md b/doc/MIGRATION-v6.md index a6305a8c6a4..ab0cae7f600 100644 --- a/doc/MIGRATION-v6.md +++ b/doc/MIGRATION-v6.md @@ -164,8 +164,7 @@ Use: ```java var resource = client.resource(deployment).inNamespace(session.getNamespace()); -resource.delete(); -resource.waitUntilCondition(Objects::isNull, 30, TimeUnit.SECONDS); +resource.withTimeout(30, TimeUnit.SECONDS).delete(); resource.create(); ``` diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/DeletableWithOptions.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/DeletableWithOptions.java index c6b3bcf5b8e..3227c322651 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/DeletableWithOptions.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/DeletableWithOptions.java @@ -19,7 +19,15 @@ import io.fabric8.kubernetes.client.GracePeriodConfigurable; import io.fabric8.kubernetes.client.PropagationPolicyConfigurable; +import java.util.concurrent.TimeUnit; + public interface DeletableWithOptions extends GracePeriodConfigurable>, - PropagationPolicyConfigurable> { + PropagationPolicyConfigurable>, Timeoutable { + + @Override + DeletableWithOptions withTimeout(long timeout, TimeUnit unit); + + @Override + DeletableWithOptions withTimeoutInMillis(long timeoutInMillis); } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/TimeoutImageEditReplacePatchable.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/TimeoutImageEditReplacePatchable.java index 91be0adff86..81930971863 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/TimeoutImageEditReplacePatchable.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/TimeoutImageEditReplacePatchable.java @@ -16,7 +16,14 @@ package io.fabric8.kubernetes.client.dsl; +import java.util.concurrent.TimeUnit; + public interface TimeoutImageEditReplacePatchable extends - Timeoutable>, - ImageEditReplacePatchable { + Timeoutable, ImageEditReplacePatchable { + + @Override + ImageEditReplacePatchable withTimeout(long timeout, TimeUnit unit); + + @Override + ImageEditReplacePatchable withTimeoutInMillis(long timeoutInMillis); } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Timeoutable.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Timeoutable.java index 04a1afed2d1..ff8c2ea8d92 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Timeoutable.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Timeoutable.java @@ -18,10 +18,21 @@ import java.util.concurrent.TimeUnit; -public interface Timeoutable { +public interface Timeoutable { - T withTimeout(long timeout, TimeUnit unit); + /** + * Wait for the given operation timeout. For list contexts it applies to each delete operation. + * + * @param timeout 0 indicates no wait + * @param unit + */ + Object withTimeout(long timeout, TimeUnit unit); + /** + * Wait for the given operation timeout in milliseconds. For list contexts it applies to each delete operation. + * + * @param timeoutInMillis 0 indicates no wait + */ + Object withTimeoutInMillis(long timeoutInMillis); - T withTimeoutInMillis(long timeoutInMillis); } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResource.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResource.java index 55f80e9ab8f..443a6f17d09 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResource.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResource.java @@ -20,9 +20,11 @@ import io.fabric8.kubernetes.client.Client; import io.fabric8.kubernetes.client.dsl.Nameable; import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.dsl.WritableOperation; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.Function; /** @@ -84,4 +86,12 @@ public interface ExtensibleResource extends Resource { @Override ExtensibleResource forceConflicts(); + @Override + ExtensibleResource withTimeout(long timeout, TimeUnit unit); + + @Override + default WritableOperation withTimeoutInMillis(long timeoutInMillis) { + return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); + } + } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResourceAdapter.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResourceAdapter.java index 6ffff08654f..26d5a1a9f78 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResourceAdapter.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ExtensibleResourceAdapter.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.Function; /** @@ -116,4 +117,14 @@ public ExtensibleResource forceConflicts() { return newInstance().init(resource.forceConflicts(), client); } + @Override + public ExtensibleResource withTimeout(long timeout, TimeUnit unit) { + return newInstance().init(resource.withTimeout(timeout, unit), client); + } + + @Override + public ExtensibleResource withTimeoutInMillis(long timeoutInMillis) { + return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); + } + } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ResourceAdapter.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ResourceAdapter.java index cd80145363b..a068e681322 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ResourceAdapter.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extension/ResourceAdapter.java @@ -26,6 +26,7 @@ import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.dsl.Deletable; +import io.fabric8.kubernetes.client.dsl.DeletableWithOptions; import io.fabric8.kubernetes.client.dsl.Gettable; import io.fabric8.kubernetes.client.dsl.Informable; import io.fabric8.kubernetes.client.dsl.NonDeletingOperation; @@ -324,4 +325,14 @@ public T serverSideApply() { return resource.serverSideApply(); } + @Override + public DeletableWithOptions withTimeout(long timeout, TimeUnit unit) { + return resource.withTimeout(timeout, unit); + } + + @Override + public DeletableWithOptions withTimeoutInMillis(long timeoutInMillis) { + return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); + } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java index 9c77ea8b3fd..cf19f11baa1 100755 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/BaseOperation.java @@ -451,6 +451,17 @@ static void toStatusDetails(KubernetesResource obj, List details) @Override public List delete() { + List deleted = deleteAll(); + if (this.context.getTimeout() > 0) { + Set uids = deleted.stream().map(StatusDetails::getUid).collect(Collectors.toSet()); + CompletableFuture> delete = this + .informOnCondition(l -> l.stream().map(i -> i.getMetadata().getUid()).noneMatch(uid -> uids.contains(uid))); + Utils.waitUntilReadyOrFail(delete, this.context.getTimeout(), this.context.getTimeoutUnit()); + } + return deleted; + } + + protected List deleteAll() { if (Utils.isNotNullOrEmpty(name) || Utils.isNotNullOrEmpty(namespace) || !isResourceNamespaced()) { try { URL resourceURLForWriteOperation = getResourceURLForWriteOperation(getResourceUrl()); @@ -1103,4 +1114,9 @@ public T serverSideApply() { return this.patch(PatchContext.of(PatchType.SERVER_SIDE_APPLY)); } + @Override + public ExtensibleResource withTimeout(long timeout, TimeUnit unit) { + return newInstance(context.withTimeout(timeout, unit)); + } + } 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 827921752d9..5bbb47e4175 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 @@ -29,6 +29,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.KubernetesClientTimeoutException; +import io.fabric8.kubernetes.client.dsl.DeletableWithOptions; import io.fabric8.kubernetes.client.dsl.Gettable; import io.fabric8.kubernetes.client.dsl.ListVisitFromServerGetDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.ListVisitFromServerWritable; @@ -337,4 +338,14 @@ public List replaceStatus() { return performOperation(Resource::replaceStatus); } + @Override + public DeletableWithOptions withTimeout(long timeout, TimeUnit unit) { + return newInstance(context.withTimeout(timeout, unit), namespaceVisitOperationContext); + } + + @Override + public DeletableWithOptions withTimeoutInMillis(long timeoutInMillis) { + return this.withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); + } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/OperationContext.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/OperationContext.java index 01c5c4e4298..d1ba99608eb 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/OperationContext.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/OperationContext.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -68,6 +69,9 @@ public class OperationContext { protected Client client; + private long timeout; + private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS; + public OperationContext() { } @@ -76,7 +80,7 @@ public OperationContext(OperationContext other) { other.item, other.labels, other.labelsNot, other.labelsIn, other.labelsNotIn, other.fields, other.fieldsNot, other.resourceVersion, other.reloadingFromServer, other.gracePeriodSeconds, other.propagationPolicy, other.dryRun, other.selectorAsString, other.defaultNamespace, other.fieldValidation, other.fieldManager, - other.forceConflicts); + other.forceConflicts, other.timeout, other.timeoutUnit); } public OperationContext(Client client, String plural, String namespace, String name, @@ -85,7 +89,7 @@ public OperationContext(Client client, String plural, String namespace, String n Map fields, Map fieldsNot, String resourceVersion, boolean reloadingFromServer, long gracePeriodSeconds, DeletionPropagation propagationPolicy, boolean dryRun, String selectorAsString, boolean defaultNamespace, FieldValidateable.Validation fieldValidation, - String fieldManager, Boolean forceConflicts) { + String fieldManager, Boolean forceConflicts, long timeout, TimeUnit timeoutUnit) { this.client = client; this.item = item; this.plural = plural; @@ -108,6 +112,8 @@ public OperationContext(Client client, String plural, String namespace, String n this.fieldValidation = fieldValidation; this.fieldManager = fieldManager; this.forceConflicts = forceConflicts; + this.timeout = timeout; + this.timeoutUnit = timeoutUnit; } private void setFieldsNot(Map fieldsNot) { @@ -243,6 +249,14 @@ public boolean getDryRun() { return dryRun; } + public long getTimeout() { + return timeout; + } + + public TimeUnit getTimeoutUnit() { + return timeoutUnit; + } + public String getLabelQueryParam() { if (Utils.isNotNullOrEmpty(selectorAsString)) { return selectorAsString; @@ -485,7 +499,8 @@ public C clientInWriteContext(Class clazz) { // operationcontext OperationContext newContext = HasMetadataOperationsImpl.defaultContext(client).withDryRun(getDryRun()) .withGracePeriodSeconds(getGracePeriodSeconds()).withPropagationPolicy(getPropagationPolicy()) - .withReloadingFromServer(isReloadingFromServer()).withFieldValidation(this.fieldValidation); + .withReloadingFromServer(isReloadingFromServer()).withFieldValidation(this.fieldValidation) + .withTimeout(this.timeout, this.timeoutUnit); // check before setting to prevent flipping the default flag if (!Objects.equals(getNamespace(), newContext.getNamespace()) @@ -527,4 +542,11 @@ public OperationContext withForceConflicts() { return context; } + public OperationContext withTimeout(long timeout, TimeUnit timeUnit) { + final OperationContext context = new OperationContext(this); + context.timeout = timeout; + context.timeoutUnit = timeUnit == null ? TimeUnit.MILLISECONDS : timeUnit; + return context; + } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/PodOperationContext.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/PodOperationContext.java index bc4ccfbf08c..2e2a625972b 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/PodOperationContext.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/PodOperationContext.java @@ -67,6 +67,8 @@ public StreamContext() { private String dir; private boolean terminateOnError; + private boolean rolling; + public PodOperationContext withContainerId(String containerId) { return this.toBuilder().containerId(containerId).build(); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/RollingOperationContext.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/RollingOperationContext.java deleted file mode 100644 index 1eabf3bb422..00000000000 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/RollingOperationContext.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (C) 2015 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.fabric8.kubernetes.client.dsl.internal; - -import java.util.concurrent.TimeUnit; - -public class RollingOperationContext { - - private final PodOperationContext podOperationContext; - private boolean rolling; - private long rollingTimeout; - private TimeUnit rollingTimeUnit; - - public RollingOperationContext() { - this.podOperationContext = new PodOperationContext(); - } - - public RollingOperationContext(PodOperationContext podOperationContext, boolean rolling, long rollingTimeout, - TimeUnit rollingTimeUnit) { - this.podOperationContext = podOperationContext; - this.rolling = rolling; - this.rollingTimeout = rollingTimeout; - this.rollingTimeUnit = rollingTimeUnit != null ? rollingTimeUnit : TimeUnit.MILLISECONDS; - } - - public PodOperationContext getPodOperationContext() { - return podOperationContext; - } - - public Boolean getRolling() { - return rolling; - } - - public long getRollingTimeout() { - return rollingTimeout; - } - - public TimeUnit getRollingTimeUnit() { - return rollingTimeUnit; - } - - public RollingOperationContext withRolling(boolean rolling) { - return new RollingOperationContext(podOperationContext, rolling, rollingTimeout, rollingTimeUnit); - } - - public RollingOperationContext withRollingTimeout(long rollingTimeout) { - return new RollingOperationContext(podOperationContext, rolling, rollingTimeout, rollingTimeUnit); - } - - public RollingOperationContext withRollingTimeUnit(TimeUnit rollingTimeUnit) { - return new RollingOperationContext(podOperationContext, rolling, rollingTimeout, rollingTimeUnit); - } - - public RollingOperationContext withContainerId(String containerId) { - return new RollingOperationContext(podOperationContext.withContainerId(containerId), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withLogWaitTimeout(Integer logWaitTimeout) { - return new RollingOperationContext(podOperationContext.withLogWaitTimeout(logWaitTimeout), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withLimitBytes(Integer limitBytes) { - return new RollingOperationContext(podOperationContext.withLimitBytes(limitBytes), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withTerminatedStatus(boolean terminatedStatus) { - return new RollingOperationContext(podOperationContext.withTerminatedStatus(terminatedStatus), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withPrettyOutput(boolean prettyOutput) { - return new RollingOperationContext(podOperationContext.withPrettyOutput(prettyOutput), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withTailingLines(Integer tailingLines) { - return new RollingOperationContext(podOperationContext.withTailingLines(tailingLines), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withSinceTimestamp(String sinceTimestamp) { - return new RollingOperationContext(podOperationContext.withSinceTimestamp(sinceTimestamp), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withSinceSeconds(Integer sinceSeconds) { - return new RollingOperationContext(podOperationContext.withSinceSeconds(sinceSeconds), rolling, rollingTimeout, - rollingTimeUnit); - } - - public RollingOperationContext withTimestamps(boolean timestamps) { - return new RollingOperationContext(podOperationContext.withTimestamps(timestamps), rolling, rollingTimeout, - rollingTimeUnit); - } - -} 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 c9e7fb13c9a..24e03e79eaf 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 @@ -35,7 +35,7 @@ import io.fabric8.kubernetes.client.dsl.TimeoutImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,10 +60,10 @@ public class DeploymentOperationsImpl public static final String DEPLOYMENT_KUBERNETES_IO_REVISION = "deployment.kubernetes.io/revision"; public DeploymentOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - public DeploymentOperationsImpl(RollingOperationContext context, OperationContext superContext) { + public DeploymentOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withApiGroupName("apps") .withApiGroupVersion("v1") .withPlural("deployments"), Deployment.class, DeploymentList.class); @@ -75,8 +75,9 @@ public DeploymentOperationsImpl newInstance(OperationContext context) { } @Override - public DeploymentOperationsImpl newInstance(RollingOperationContext context) { - return new DeploymentOperationsImpl(context, this.context); + public DeploymentOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new DeploymentOperationsImpl(context, superContext); } @Override @@ -217,8 +218,7 @@ private List> doGetLog() { Deployment deployment = requireFromServer(); String rcUid = deployment.getMetadata().getUid(); - ReplicaSetOperationsImpl rsOperations = new ReplicaSetOperationsImpl( - new RollingOperationContext(rollingOperationContext.getPodOperationContext(), false, 0, null), + ReplicaSetOperationsImpl rsOperations = new ReplicaSetOperationsImpl(rollingOperationContext, context.withName(null)); ReplicaSetList rcList = rsOperations.withLabels(getDeploymentSelectorLabels(deployment)).list(); @@ -321,4 +321,5 @@ public TailPrettyLoggable sinceSeconds(int seconds) { public BytesLimitTerminateTimeTailPrettyLoggable usingTimestamps() { return new DeploymentOperationsImpl(rollingOperationContext.withTimestamps(true), context); } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetOperationsImpl.java index 61f137d7895..c39d47f514f 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/ReplicaSetOperationsImpl.java @@ -33,7 +33,7 @@ import io.fabric8.kubernetes.client.dsl.TimeoutImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; import io.fabric8.kubernetes.client.utils.internal.PodOperationUtil; import java.io.InputStream; @@ -49,10 +49,10 @@ public class ReplicaSetOperationsImpl implements TimeoutImageEditReplacePatchable { public ReplicaSetOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - ReplicaSetOperationsImpl(RollingOperationContext context, OperationContext superContext) { + ReplicaSetOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withApiGroupName("apps") .withApiGroupVersion("v1") .withPlural("replicasets"), ReplicaSet.class, ReplicaSetList.class); @@ -64,8 +64,9 @@ public ReplicaSetOperationsImpl newInstance(OperationContext context) { } @Override - public ReplicaSetOperationsImpl newInstance(RollingOperationContext context) { - return new ReplicaSetOperationsImpl(context, this.context); + public ReplicaSetOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new ReplicaSetOperationsImpl(context, superContext); } @Override @@ -129,7 +130,7 @@ public String getLog(boolean isPretty) { private List doGetLog() { ReplicaSet replicaSet = requireFromServer(); return PodOperationUtil.getPodOperationsForController(context, - rollingOperationContext.getPodOperationContext(), replicaSet.getMetadata().getUid(), + rollingOperationContext, replicaSet.getMetadata().getUid(), getReplicaSetSelectorLabels(replicaSet)); } 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 0f424dcbc93..7c6d82dca2b 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 @@ -21,7 +21,6 @@ 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.ImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.LogWatch; import io.fabric8.kubernetes.client.dsl.Loggable; import io.fabric8.kubernetes.client.dsl.Resource; @@ -31,7 +30,7 @@ import io.fabric8.kubernetes.client.dsl.base.PatchType; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperation; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; import io.fabric8.kubernetes.client.utils.Serialization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,18 +51,12 @@ public abstract class RollableScalableResourceOperation type, + protected RollableScalableResourceOperation(PodOperationContext context, OperationContext superContext, Class type, Class listType) { super(superContext, type, listType); this.rollingOperationContext = context; - this.rolling = context.getRolling(); - this.rollingTimeout = context.getRollingTimeout(); - this.rollingTimeUnit = context.getRollingTimeUnit(); } protected abstract T withReplicas(int count); @@ -143,13 +136,13 @@ private T waitUntilScaled(final int count) { @Override public T edit(UnaryOperator function) { - if (!rolling) { + if (!rollingOperationContext.isRolling()) { return super.edit(function); } try { T oldObj = getMandatory(); T newObj = function.apply(Serialization.clone(oldObj)); - return getRollingUpdater(rollingTimeout, rollingTimeUnit).rollUpdate(oldObj, newObj); + return getRollingUpdater(context.getTimeout(), context.getTimeoutUnit()).rollUpdate(oldObj, newObj); } catch (Exception e) { throw KubernetesClientException.launderThrowable(e); } @@ -157,50 +150,41 @@ public T edit(UnaryOperator function) { @Override public T replace(T t) { - if (!rolling) { + if (!rollingOperationContext.isRolling()) { return super.replace(t); } - return getRollingUpdater(rollingTimeout, rollingTimeUnit).rollUpdate(getMandatory(), t); + return getRollingUpdater(context.getTimeout(), context.getTimeoutUnit()).rollUpdate(getMandatory(), t); } @Override public T patch(PatchContext patchContext, T item) { - if (!rolling || patchContext == null || patchContext.getPatchType() != PatchType.JSON) { + if (!rollingOperationContext.isRolling() || patchContext == null || patchContext.getPatchType() != PatchType.JSON) { return super.patch(patchContext, item); } - return getRollingUpdater(rollingTimeout, rollingTimeUnit).rollUpdate(getMandatory(), item); + return getRollingUpdater(context.getTimeout(), context.getTimeoutUnit()).rollUpdate(getMandatory(), item); } - public abstract RollableScalableResourceOperation newInstance(RollingOperationContext context); + public abstract RollableScalableResourceOperation newInstance(PodOperationContext context, + OperationContext superContext); @Override public Loggable withLogWaitTimeout(Integer logWaitTimeout) { - return newInstance(rollingOperationContext.withLogWaitTimeout(logWaitTimeout)); + return newInstance(rollingOperationContext.withLogWaitTimeout(logWaitTimeout), context); } @Override public Loggable inContainer(String id) { - return newInstance(rollingOperationContext.withContainerId(id)); + return newInstance(rollingOperationContext.withContainerId(id), context); } @Override public TimeoutImageEditReplacePatchable rolling() { - return newInstance(rollingOperationContext.withRolling(true)); - } - - @Override - public ImageEditReplacePatchable withTimeoutInMillis(long timeoutInMillis) { - return newInstance(rollingOperationContext.withRollingTimeout(timeoutInMillis).withRollingTimeUnit(TimeUnit.MILLISECONDS)); - } - - @Override - public ImageEditReplacePatchable withTimeout(long timeout, TimeUnit unit) { - return newInstance(rollingOperationContext.withRollingTimeout(timeout).withRollingTimeUnit(unit)); + return newInstance(rollingOperationContext.toBuilder().rolling(true).build(), context); } @Override public String getLog() { - return getLog(rollingOperationContext.getPodOperationContext().isPrettyOutput()); + return getLog(rollingOperationContext.isPrettyOutput()); } @Override @@ -259,4 +243,14 @@ protected T sendPatchedObject(T oldObject, T updatedObject) { return this.patch(null, oldObject, updatedObject, false); } + @Override + public RollableScalableResourceOperation withTimeout(long timeout, TimeUnit unit) { + return newInstance(rollingOperationContext, context.withTimeout(timeout, unit)); + } + + @Override + public RollableScalableResourceOperation withTimeoutInMillis(long timeoutInMillis) { + return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); + } + } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetOperationsImpl.java index 0d6fd9736b4..c2dc2207d92 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/apps/v1/StatefulSetOperationsImpl.java @@ -37,7 +37,7 @@ import io.fabric8.kubernetes.client.dsl.base.PatchType; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.kubernetes.client.utils.internal.PodOperationUtil; @@ -53,10 +53,10 @@ public class StatefulSetOperationsImpl extends RollableScalableResourceOperation> implements TimeoutImageEditReplacePatchable { public StatefulSetOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - public StatefulSetOperationsImpl(RollingOperationContext context, OperationContext superContext) { + public StatefulSetOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withApiGroupName("apps") .withApiGroupVersion("v1") .withPlural("statefulsets"), StatefulSet.class, StatefulSetList.class); @@ -68,8 +68,9 @@ public StatefulSetOperationsImpl newInstance(OperationContext context) { } @Override - public StatefulSetOperationsImpl newInstance(RollingOperationContext context) { - return new StatefulSetOperationsImpl(context, this.context); + public StatefulSetOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new StatefulSetOperationsImpl(context, superContext); } @Override @@ -114,7 +115,7 @@ private List doGetLog() { StatefulSet statefulSet = requireFromServer(); return PodOperationUtil.getPodOperationsForController(context, - rollingOperationContext.getPodOperationContext(), statefulSet.getMetadata().getUid(), + rollingOperationContext, statefulSet.getMetadata().getUid(), getStatefulSetSelectorLabels(statefulSet)); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerOperationsImpl.java index 2d8007d29ba..0fcc6eacd1a 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/core/v1/ReplicationControllerOperationsImpl.java @@ -33,7 +33,7 @@ import io.fabric8.kubernetes.client.dsl.TimeoutImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; 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.internal.PodOperationUtil; @@ -51,10 +51,10 @@ public class ReplicationControllerOperationsImpl extends implements TimeoutImageEditReplacePatchable { public ReplicationControllerOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - public ReplicationControllerOperationsImpl(RollingOperationContext context, OperationContext superContext) { + public ReplicationControllerOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withPlural("replicationcontrollers"), ReplicationController.class, ReplicationControllerList.class); } @@ -65,8 +65,9 @@ public ReplicationControllerOperationsImpl newInstance(OperationContext context) } @Override - public ReplicationControllerOperationsImpl newInstance(RollingOperationContext context) { - return new ReplicationControllerOperationsImpl(context, this.context); + public ReplicationControllerOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new ReplicationControllerOperationsImpl(context, superContext); } @Override @@ -113,7 +114,7 @@ private List doGetLog() { ReplicationController rc = requireFromServer(); return PodOperationUtil.getPodOperationsForController(context, - rollingOperationContext.getPodOperationContext(), rc.getMetadata().getUid(), + rollingOperationContext, rc.getMetadata().getUid(), getReplicationControllerPodLabels(rc)); } 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 deb226f691f..e2ef43fd8e3 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 @@ -35,7 +35,7 @@ import io.fabric8.kubernetes.client.dsl.TimeoutImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; 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; @@ -62,10 +62,10 @@ public class DeploymentOperationsImpl public static final String DEPLOYMENT_KUBERNETES_IO_REVISION = "deployment.kubernetes.io/revision"; public DeploymentOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - public DeploymentOperationsImpl(RollingOperationContext context, OperationContext superContext) { + public DeploymentOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withApiGroupName("extensions") .withApiGroupVersion("v1beta1") .withPlural("deployments"), Deployment.class, DeploymentList.class); @@ -77,8 +77,9 @@ public DeploymentOperationsImpl newInstance(OperationContext context) { } @Override - public DeploymentOperationsImpl newInstance(RollingOperationContext context) { - return new DeploymentOperationsImpl(context, this.context); + public DeploymentOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new DeploymentOperationsImpl(context, superContext); } @Override @@ -215,8 +216,7 @@ private List> doGetLog() { String rcUid = deployment.getMetadata().getUid(); ReplicaSetOperationsImpl rsOperations = new ReplicaSetOperationsImpl( - new RollingOperationContext(rollingOperationContext.getPodOperationContext(), false, 0, null), - context.withName(null)); + rollingOperationContext, context.withName(null)); ReplicaSetList rcList = rsOperations.withLabels(getDeploymentSelectorLabels(deployment)).list(); for (ReplicaSet rs : rcList.getItems()) { diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetOperationsImpl.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetOperationsImpl.java index 83c815542fd..3200968b93b 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetOperationsImpl.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/extensions/v1beta1/ReplicaSetOperationsImpl.java @@ -22,10 +22,18 @@ import io.fabric8.kubernetes.api.model.extensions.ReplicaSetList; import io.fabric8.kubernetes.client.Client; import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.dsl.*; +import io.fabric8.kubernetes.client.dsl.BytesLimitTerminateTimeTailPrettyLoggable; +import io.fabric8.kubernetes.client.dsl.LogWatch; +import io.fabric8.kubernetes.client.dsl.Loggable; +import io.fabric8.kubernetes.client.dsl.PodResource; +import io.fabric8.kubernetes.client.dsl.PrettyLoggable; +import io.fabric8.kubernetes.client.dsl.RollableScalableResource; +import io.fabric8.kubernetes.client.dsl.TailPrettyLoggable; +import io.fabric8.kubernetes.client.dsl.TimeTailPrettyLoggable; +import io.fabric8.kubernetes.client.dsl.TimeoutImageEditReplacePatchable; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; 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.internal.PodOperationUtil; @@ -43,10 +51,10 @@ public class ReplicaSetOperationsImpl implements TimeoutImageEditReplacePatchable { public ReplicaSetOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - ReplicaSetOperationsImpl(RollingOperationContext context, OperationContext superContext) { + ReplicaSetOperationsImpl(PodOperationContext context, OperationContext superContext) { super(context, superContext.withApiGroupName("extensions") .withApiGroupVersion("v1beta1") .withPlural("replicasets"), ReplicaSet.class, ReplicaSetList.class); @@ -58,8 +66,9 @@ public ReplicaSetOperationsImpl newInstance(OperationContext context) { } @Override - public ReplicaSetOperationsImpl newInstance(RollingOperationContext context) { - return new ReplicaSetOperationsImpl(context, this.context); + public ReplicaSetOperationsImpl newInstance(PodOperationContext context, + OperationContext superContext) { + return new ReplicaSetOperationsImpl(context, superContext); } @Override @@ -128,7 +137,7 @@ public String getLog(boolean isPretty) { private List doGetLog() { ReplicaSet replicaSet = requireFromServer(); return PodOperationUtil.getPodOperationsForController(context, - rollingOperationContext.getPodOperationContext(), replicaSet.getMetadata().getUid(), + rollingOperationContext, replicaSet.getMetadata().getUid(), getReplicaSetSelectorLabels(replicaSet)); } diff --git a/kubernetes-itests/pom.xml b/kubernetes-itests/pom.xml index b46a97c2fdc..4db1a13cd36 100644 --- a/kubernetes-itests/pom.xml +++ b/kubernetes-itests/pom.xml @@ -50,6 +50,11 @@ openshift-client test + + io.fabric8 + kubernetes-client-api + test-jar + org.assertj assertj-core diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DeleteIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DeleteIT.java index f073023c4a2..c4e2eeab8c1 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DeleteIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/DeleteIT.java @@ -17,14 +17,21 @@ import io.fabric8.junit.jupiter.api.LoadKubernetesManifests; import io.fabric8.kubernetes.api.model.DeletionPropagation; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.StatusDetails; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.ReplicaSet; import io.fabric8.kubernetes.api.model.apps.ReplicaSetList; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.utils.CommonThreadPool; import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -47,14 +54,44 @@ void testDeleteNonExistentResource() { } @Test - void testDeleteExistentResource() { + void testDeleteNonExistentResourceBlocking() { + // Given + String podName = "i-dont-exist"; + // When + long start = System.currentTimeMillis(); + client.pods().withName(podName).withTimeout(10, TimeUnit.MINUTES).delete(); + // Then it shouldn't block + assertTrue(System.currentTimeMillis() - start < TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES)); + } + + @Test + void testBlockingDeleteExistentResource() throws Exception { // Given String name = "deleteit-existent"; // When - boolean isDeleted = client.secrets().withName(name).delete().size() == 1; - // Then - assertTrue(isDeleted); - client.secrets().withName(name).waitUntilCondition(Objects::isNull, 60, TimeUnit.SECONDS); + Resource op = client.secrets().withName(name); + CompletableFuture> future; + try { + op.edit(s -> { + s.addFinalizer("fabric8.com/blocking"); + return s; + }); + future = CompletableFuture.supplyAsync(() -> op.withTimeout(60, TimeUnit.SECONDS).delete(), CommonThreadPool.get()); + + try { + future.get(10, TimeUnit.SECONDS); + } catch (TimeoutException e) { + // expected - we're waiting for the finalizer + } + assertNotNull(op.get().getMetadata().getDeletionTimestamp()); + } finally { + op.edit(s -> { + s.getMetadata().setFinalizers(null); + return s; + }); + } + + assertEquals(1, future.get(60, TimeUnit.SECONDS).size()); } @Test 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 1809292addb..5bb00ff8adc 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 @@ -43,7 +43,6 @@ import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @@ -170,8 +169,7 @@ void testCreateOrReplaceWithDeleteExisting() throws Exception { ListVisitFromServerGetDeleteRecreateWaitApplicable resourceList = client.resourceList(resourcesToUpdate) .inNamespace("ns1"); - resourceList.delete(); - resourceList.waitUntilCondition(Objects::isNull, 10, TimeUnit.SECONDS); + resourceList.withTimeout(10, TimeUnit.SECONDS).delete(); resourceList.createOrReplace(); assertEquals(6, server.getRequestCount()); diff --git a/openshift-client-api/src/main/java/io/fabric8/openshift/client/dsl/TimeoutInputStreamable.java b/openshift-client-api/src/main/java/io/fabric8/openshift/client/dsl/TimeoutInputStreamable.java index b73dc92dc10..e22c538b00e 100644 --- a/openshift-client-api/src/main/java/io/fabric8/openshift/client/dsl/TimeoutInputStreamable.java +++ b/openshift-client-api/src/main/java/io/fabric8/openshift/client/dsl/TimeoutInputStreamable.java @@ -18,7 +18,15 @@ import io.fabric8.kubernetes.client.dsl.Timeoutable; +import java.util.concurrent.TimeUnit; + public interface TimeoutInputStreamable extends - Timeoutable>, - InputStreamable { + Timeoutable, + InputStreamable { + + @Override + InputStreamable withTimeout(long timeout, TimeUnit unit); + + @Override + InputStreamable withTimeoutInMillis(long timeoutInMillis); } diff --git a/openshift-client/pom.xml b/openshift-client/pom.xml index 9cccc3db2b4..6ce6e0d0265 100644 --- a/openshift-client/pom.xml +++ b/openshift-client/pom.xml @@ -78,6 +78,11 @@ io.sundr transform-annotations + + + org.projectlombok + lombok + org.apache.felix diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/BuildConfigOperationContext.java b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/BuildConfigOperationContext.java index c39e251b80a..6202c3f8e89 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/BuildConfigOperationContext.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/BuildConfigOperationContext.java @@ -15,8 +15,15 @@ */ package io.fabric8.openshift.client.dsl.internal; -import java.util.concurrent.TimeUnit; - +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Getter public class BuildConfigOperationContext { private String secret; @@ -30,112 +37,40 @@ public class BuildConfigOperationContext { private String message; private String asFile; - private long timeout; - private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS; - - public BuildConfigOperationContext() { - } - - public BuildConfigOperationContext(String secret, String triggerType, String authorName, String authorEmail, String committerName, String committerEmail, String commit, String message, String asFile, Long timeout, TimeUnit timeUnit) { - this.secret = secret; - this.triggerType = triggerType; - this.authorName = authorName; - this.authorEmail = authorEmail; - this.committerName = committerName; - this.committerEmail = committerEmail; - this.commit = commit; - this.message = message; - this.asFile = asFile; - this.timeout = timeout; - this.timeoutUnit = timeUnit != null ? timeUnit : TimeUnit.MILLISECONDS; - } - - public String getSecret() { - return secret; - } - - public String getTriggerType() { - return triggerType; - } - - public String getAuthorName() { - return authorName; - } - - public String getAuthorEmail() { - return authorEmail; - } - - public String getCommitterName() { - return committerName; - } - - public String getCommitterEmail() { - return committerEmail; - } - - public String getCommit() { - return commit; - } - - public String getMessage() { - return message; - } - - public String getAsFile() { - return asFile; - } - - public long getTimeout() { - return timeout; - } - - public TimeUnit getTimeoutUnit() { - return timeoutUnit; - } - public BuildConfigOperationContext withSecret(String secret) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().secret(secret).build(); } public BuildConfigOperationContext withTriggerType(String triggerType) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().triggerType(triggerType).build(); } public BuildConfigOperationContext withAuthorName(String authorName) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().authorName(authorName).build(); } public BuildConfigOperationContext withAuthorEmail(String authorEmail) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().authorEmail(authorEmail).build(); } public BuildConfigOperationContext withCommitterName(String committerName) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().committerName(committerName).build(); } public BuildConfigOperationContext withCommitterEmail(String committerEmail) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().committerEmail(committerEmail).build(); } public BuildConfigOperationContext withCommit(String commit) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().commit(commit).build(); } public BuildConfigOperationContext withMessage(String message) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().message(message).build(); } public BuildConfigOperationContext withAsFile(String asFile) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); - } - - public BuildConfigOperationContext withTimeout(long timeout) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); - } - - public BuildConfigOperationContext withTimeoutUnit(TimeUnit timeoutUnit) { - return new BuildConfigOperationContext(secret, triggerType, authorName, authorEmail, committerName, committerEmail, commit, message,asFile, timeout, timeoutUnit); + return toBuilder().asFile(asFile).build(); } } 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 a54eb4f717a..b121c75077d 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 @@ -30,9 +30,8 @@ import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.LogWatchCallback; import io.fabric8.kubernetes.client.dsl.internal.OperationContext; -import io.fabric8.kubernetes.client.dsl.internal.RollingOperationContext; +import io.fabric8.kubernetes.client.dsl.internal.PodOperationContext; import io.fabric8.kubernetes.client.utils.URLUtils; -import io.fabric8.kubernetes.client.utils.URLUtils.URLBuilder; import io.fabric8.kubernetes.client.utils.internal.PodOperationUtil; import io.fabric8.openshift.api.model.DeploymentConfig; import io.fabric8.openshift.api.model.DeploymentConfigList; @@ -61,13 +60,13 @@ public class DeploymentConfigOperationsImpl private static final Logger LOG = LoggerFactory.getLogger(DeploymentConfigOperationsImpl.class); private static final Integer DEFAULT_POD_LOG_WAIT_TIMEOUT = 5; public static final String OPENSHIFT_IO_DEPLOYMENT_CONFIG_NAME = "openshift.io/deployment-config.name"; - private final RollingOperationContext rollingOperationContext; + private final PodOperationContext rollingOperationContext; public DeploymentConfigOperationsImpl(Client client) { - this(new RollingOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); + this(new PodOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } - public DeploymentConfigOperationsImpl(RollingOperationContext context, OperationContext superContext) { + public DeploymentConfigOperationsImpl(PodOperationContext context, OperationContext superContext) { super(superContext.withApiGroupName(APPS).withPlural("deploymentconfigs"), DeploymentConfig.class, DeploymentConfigList.class); this.rollingOperationContext = context; @@ -165,7 +164,7 @@ private void waitUntilDeploymentConfigIsScaled(final int count) { @Override public String getLog() { - return getLog(rollingOperationContext.getPodOperationContext().isPrettyOutput()); + return getLog(rollingOperationContext.isPrettyOutput()); } @Override @@ -224,10 +223,10 @@ public LogWatch watchLog(OutputStream out) { private URL getResourceLogUrl(Boolean follow) throws MalformedURLException { if (Boolean.TRUE.equals(follow)) { return new URL(URLUtils.join(getResourceUrl().toString(), - rollingOperationContext.getPodOperationContext().getLogParameters() + "&follow=true")); + rollingOperationContext.getLogParameters() + "&follow=true")); } else { return new URL( - URLUtils.join(getResourceUrl().toString(), rollingOperationContext.getPodOperationContext().getLogParameters())); + URLUtils.join(getResourceUrl().toString(), rollingOperationContext.getLogParameters())); } } @@ -237,9 +236,9 @@ public Loggable withLogWaitTimeout(Integer logWaitTimeout) { } private void waitUntilDeploymentConfigPodBecomesReady(DeploymentConfig deploymentConfig) { - Integer podLogWaitTimeout = rollingOperationContext.getPodOperationContext().getLogWaitTimeout(); + Integer podLogWaitTimeout = rollingOperationContext.getLogWaitTimeout(); List podOps = PodOperationUtil.getPodOperationsForController(context, - rollingOperationContext.getPodOperationContext(), + rollingOperationContext, deploymentConfig.getMetadata().getUid(), getDeploymentConfigPodLabels(deploymentConfig)); waitForBuildPodToBecomeReady(podOps, podLogWaitTimeout != null ? podLogWaitTimeout : DEFAULT_POD_LOG_WAIT_TIMEOUT); diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/build/BuildConfigOperationsImpl.java b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/build/BuildConfigOperationsImpl.java index 60a8f11a282..165872e6ecc 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/build/BuildConfigOperationsImpl.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/dsl/internal/build/BuildConfigOperationsImpl.java @@ -36,7 +36,6 @@ import io.fabric8.openshift.api.model.BuildRequest; import io.fabric8.openshift.api.model.WebHookTrigger; import io.fabric8.openshift.client.dsl.BuildConfigResource; -import io.fabric8.openshift.client.dsl.InputStreamable; import io.fabric8.openshift.client.dsl.TimeoutInputStreamable; import io.fabric8.openshift.client.dsl.buildconfig.AsFileTimeoutInputStreamable; import io.fabric8.openshift.client.dsl.buildconfig.AuthorEmailable; @@ -80,9 +79,6 @@ public class BuildConfigOperationsImpl private final String message; private final String asFile; - private final long timeout; - private final TimeUnit timeoutUnit; - public BuildConfigOperationsImpl(Client client) { this(new BuildConfigOperationContext(), HasMetadataOperationsImpl.defaultContext(client)); } @@ -100,8 +96,6 @@ public BuildConfigOperationsImpl(BuildConfigOperationContext context, OperationC this.commit = context.getCommit(); this.message = context.getMessage(); this.asFile = context.getAsFile(); - this.timeout = context.getTimeout(); - this.timeoutUnit = context.getTimeoutUnit(); } @Override @@ -244,12 +238,12 @@ public CommitterEmailable> with } @Override - public InputStreamable withTimeout(long timeout, TimeUnit unit) { - return new BuildConfigOperationsImpl(getContext().withTimeout(timeout).withTimeoutUnit(unit), context); + public BuildConfigOperationsImpl withTimeout(long timeout, TimeUnit unit) { + return new BuildConfigOperationsImpl(getContext(), context.withTimeout(timeout, unit)); } @Override - public InputStreamable withTimeoutInMillis(long timeoutInMillis) { + public BuildConfigOperationsImpl withTimeoutInMillis(long timeoutInMillis) { return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS); } @@ -261,8 +255,8 @@ public Typeable> withSecret(String secret) { protected Build submitToApiServer(InputStream inputStream, long contentLength) { try { HttpClient newClient = this.httpClient.newBuilder() - .readTimeout(timeout, timeoutUnit) - .writeTimeout(timeout, timeoutUnit) + .readTimeout(this.context.getTimeout(), this.context.getTimeoutUnit()) + .writeTimeout(this.context.getTimeout(), this.context.getTimeoutUnit()) .build(); HttpRequest.Builder requestBuilder = this.httpClient.newHttpRequestBuilder() .post("application/octet-stream", inputStream, contentLength)