diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Client.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Client.java index 514fe1e36d1..62cbc014972 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Client.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/Client.java @@ -112,6 +112,6 @@ , R extends Resource< */ default > MixedOperation> resources( Class resourceType, Class listClass) { - return resources(resourceType, listClass, Resource.class); + return resources(resourceType, listClass, null); } } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java index b9ff02a98a3..4b8204bd2af 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java @@ -73,8 +73,8 @@ import io.fabric8.kubernetes.client.dsl.MetricAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.Namespaceable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; @@ -176,6 +176,7 @@ default MixedOperation, Res * @param L type represents resource list type * @return returns a MixedOperation object with which you can do basic resource operations. If the class is a known type the dsl operation logic will be used. */ + @Override > MixedOperation> resources(Class resourceType, Class listClass); /** @@ -417,7 +418,7 @@ default MixedOperation type of Kubernetes resource * @return operations object for Kubernetes resource */ - NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(T is); + NamespaceableResource resource(T is); /** * KubernetesResource operations. You can pass any Kubernetes resource as string object and do @@ -426,7 +427,7 @@ default MixedOperation resource(String s); + NamespaceableResource resource(String s); /** * Operations for Binding resource in APIgroup core/v1 diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceableResource.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceableResource.java new file mode 100644 index 00000000000..bca9942dceb --- /dev/null +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceableResource.java @@ -0,0 +1,22 @@ +/** + * 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; + +public interface NamespaceableResource extends Resource { + + Resource inNamespace(String name); +} diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/base/ResourceDefinitionContext.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/base/ResourceDefinitionContext.java index f5aad38fe01..1ef81767071 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/base/ResourceDefinitionContext.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/base/ResourceDefinitionContext.java @@ -17,6 +17,7 @@ import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.KubernetesResource; +import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.utils.Utils; public class ResourceDefinitionContext { @@ -41,11 +42,11 @@ public String getVersion() { public String getKind() { return kind; } - + public boolean isNamespaceScoped() { return namespaced; } - + protected void validate() { if (plural == null) { if (kind == null) { @@ -56,13 +57,18 @@ protected void validate() { } public static ResourceDefinitionContext fromResourceType(Class resource) { - return new Builder() - .withGroup(HasMetadata.getGroup(resource)) - .withVersion(HasMetadata.getVersion(resource)) - .withNamespaced(Utils.isResourceNamespaced(resource)) - .withPlural(HasMetadata.getPlural(resource)) - .withKind(HasMetadata.getKind(resource)) - .build(); + try { + return new Builder() + .withGroup(HasMetadata.getGroup(resource)) + .withVersion(HasMetadata.getVersion(resource)) + .withNamespaced(Utils.isResourceNamespaced(resource)) + .withPlural(HasMetadata.getPlural(resource)) + .withKind(HasMetadata.getKind(resource)) + .build(); + } catch (IllegalArgumentException e) { + throw new KubernetesClientException( + String.format("%s is not annotated appropriately: %s", resource.getName(), e.getMessage()), e); + } } public static class Builder { @@ -96,7 +102,7 @@ public Builder withKind(String kind) { this.resourceDefinitionContext.kind = kind; return this; } - + public ResourceDefinitionContext build() { this.resourceDefinitionContext.validate(); return this.resourceDefinitionContext; diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/AutoAdaptableKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/AutoAdaptableKubernetesClient.java index bb9b4aef5cc..6471ecbc119 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/AutoAdaptableKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/AutoAdaptableKubernetesClient.java @@ -165,12 +165,12 @@ public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resource(HasMetadata is) { + public NamespaceableResource resource(HasMetadata is) { return delegate.resource(is); } @Override - public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(String s) { + public NamespaceableResource resource(String s) { return delegate.resource(s); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseClient.java index c616734976c..df033ab21ea 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseClient.java @@ -167,7 +167,7 @@ protected SimpleClientContext newState(Config updated) { @Override public , R extends Resource> MixedOperation resources( Class resourceType, Class listClass, Class resourceClass) { - // TODO: make this more robust + // TODO: make this more robust - list and resource class could be null return Handlers.getOperation(resourceType, listClass, this); } diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseKubernetesClient.java index 0ebb8d76c27..c042e970cc8 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/BaseKubernetesClient.java @@ -78,7 +78,7 @@ import io.fabric8.kubernetes.client.dsl.MetricAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; @@ -95,20 +95,19 @@ import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext; import io.fabric8.kubernetes.client.dsl.internal.HasMetadataOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.KubernetesListOperationsImpl; +import io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.DeploymentOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.ReplicaSetOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.apps.v1.StatefulSetOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.batch.v1.JobOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.batch.v1beta1.CronJobOperationsImpl; -import io.fabric8.kubernetes.client.dsl.internal.KubernetesListOperationsImpl; -import io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl; -import io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl; +import io.fabric8.kubernetes.client.dsl.internal.certificates.v1.CertificateSigningRequestOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.BindingOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.ComponentStatusOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.ReplicationControllerOperationsImpl; import io.fabric8.kubernetes.client.dsl.internal.core.v1.ServiceOperationsImpl; -import io.fabric8.kubernetes.client.dsl.internal.certificates.v1.CertificateSigningRequestOperationsImpl; import io.fabric8.kubernetes.client.extended.run.RunConfigBuilder; import io.fabric8.kubernetes.client.extended.run.RunOperations; import io.fabric8.kubernetes.client.extended.run.RunOperationsImpl; @@ -251,20 +250,20 @@ public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resourceList(String s) { return resourceListFor(s); } - - /** - * {@inheritDoc} - */ + @Override - public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(HasMetadata item) { - return new NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(this, item); + public NamespaceableResource resource(T item) { + // lookup the operation given the item + ResourceHandler resourceHandler = Handlers.get(item, this); + HasMetadataOperation op = resourceHandler.operation(this, null); + return new NamespaceableResourceAdapter(item, op); } /** * {@inheritDoc} */ @Override - public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(String s) { + public NamespaceableResource resource(String s) { return resource((HasMetadata)Serialization.unmarshal(s)); } @@ -469,6 +468,9 @@ public MixedOperation> HasMetadataOperation> resources( Class resourceType, Class listClass) { try { + if (GenericKubernetesResource.class.equals(resourceType)) { + throw new KubernetesClientException("resources cannot be called with a generic type"); + } return Handlers.getOperation(resourceType, listClass, this); } catch (Exception e) { //may be the wrong list type, try more general diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/Handlers.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/Handlers.java index d7f35637c25..88e874893b4 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/Handlers.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/Handlers.java @@ -58,6 +58,9 @@ public static void unregister(Class type) { /** * Returns a {@link ResourceHandler} for the given item. The client is optional, if it is supplied, then the server can be * consulted for resource metadata if a generic item is passed in. + * + * @return the handler + * @throws KubernetesClientException if a handler cannot be found */ public static > ResourceHandler get(T meta, BaseClient client) { Class type = (Class)meta.getClass(); @@ -70,7 +73,11 @@ public static > Resource } } - return get(type); + ResourceHandler result = get(type); + if (result == null) { + throw new KubernetesClientException("Could not find a registered handler for item: [" + meta + "]."); + } + return result; } public static ResourceDefinitionContext getResourceDefinitionContext(String apiVersion, String kind, BaseClient client) { diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/NamespaceableResourceAdapter.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/NamespaceableResourceAdapter.java new file mode 100644 index 00000000000..ca0b453afbc --- /dev/null +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/NamespaceableResourceAdapter.java @@ -0,0 +1,301 @@ +/** + * 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; + +import io.fabric8.kubernetes.api.builder.Visitor; +import io.fabric8.kubernetes.api.model.DeletionPropagation; +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.ListOptions; +import io.fabric8.kubernetes.api.model.ObjectMeta; +import io.fabric8.kubernetes.client.dsl.Deletable; +import io.fabric8.kubernetes.client.dsl.EditReplacePatchDeletable; +import io.fabric8.kubernetes.client.dsl.Gettable; +import io.fabric8.kubernetes.client.dsl.Informable; +import io.fabric8.kubernetes.client.dsl.Namespaceable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; +import io.fabric8.kubernetes.client.dsl.ReplaceDeletable; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.dsl.Waitable; +import io.fabric8.kubernetes.client.dsl.WatchAndWaitable; +import io.fabric8.kubernetes.client.dsl.WritableOperation; +import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; +import io.fabric8.kubernetes.client.dsl.base.PatchContext; +import io.fabric8.kubernetes.client.informers.ResourceEventHandler; +import io.fabric8.kubernetes.client.informers.SharedIndexInformer; +import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; +import io.fabric8.kubernetes.client.utils.Serialization; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; + +/** + * Provides a wrapper to namespace a resource. + *

+ * {@link NamespaceableResource} is not {@link Namespaceable} to allow for future versions of the logic + * to be consolidated. + *

+ * With generic typed interface design Namespacable and Namespaceable are considered incompatible no matter the types for X and Y, + * but NamespaceableX and NamespaceableY can be polymorphic. As long as there is no usage expectation + * like instanceof Namespaceable - then it would be fine to have the non-generic versions. + *

+ * The constructor and the inNamespace method determine the namespacing rules: + * - if the item is namespaced, the resource context will use that namespace as that is not currently the default behavior of withItem + */ +public class NamespaceableResourceAdapter implements NamespaceableResource { + + protected final T item; + protected final HasMetadataOperation operation; + protected final Resource resource; + + public NamespaceableResourceAdapter(T item, HasMetadataOperation op) { + this.operation = op; + this.item = item; + String namespace = KubernetesResourceUtil.getNamespace(item); + if (namespace != null) { + this.resource = op.inNamespace(namespace).withItem(item); + } else { + this.resource = op.withItem(item); + } + } + + @Override + public Resource inNamespace(String name) { + return operation.inNamespace(name).withItem(setItemNamespace(item, name)); + } + + // TODO: move to KubernetesResourceUtil + static T setItemNamespace(T item, String name) { + item = Serialization.clone(item); + if (item.getMetadata() == null) { + item.setMetadata(new ObjectMeta()); + } + item.getMetadata().setNamespace(name); + return item; + } + + @Override + public Boolean delete() { + return resource.delete(); + } + + @Override + public boolean isReady() { + return resource.isReady(); + } + + @Override + public T get() { + return resource.get(); + } + + @Override + public ReplaceDeletable lockResourceVersion(String resourceVersion) { + return resource.lockResourceVersion(resourceVersion); + } + + @Override + public EditReplacePatchDeletable cascading(boolean enabled) { + return resource.cascading(enabled); + } + + @Override + public WritableOperation dryRun() { + return resource.dryRun(); + } + + @Override + public T replace(T item) { + return resource.replace(item); + } + + @Override + public T updateStatus(T item) { + return resource.updateStatus(item); + } + + @Override + public WatchAndWaitable withResourceVersion(String resourceVersion) { + return resource.withResourceVersion(resourceVersion); + } + + @Override + public Gettable fromServer() { + return resource.fromServer(); + } + + @Override + public T replaceStatus(T item) { + return resource.replaceStatus(item); + } + + @Override + public T create(T... item) { + return resource.create(item); + } + + @Override + public Deletable withGracePeriod(long gracePeriodSeconds) { + return resource.withGracePeriod(gracePeriodSeconds); + } + + @Override + public T createOrReplace(T... item) { + return resource.createOrReplace(item); + } + + @Override + public T create(T item) { + return resource.create(item); + } + + @Override + public T editStatus(UnaryOperator function) { + return resource.editStatus(function); + } + + @Override + public T require() throws ResourceNotFoundException { + return resource.require(); + } + + @Override + public EditReplacePatchDeletable withPropagationPolicy(DeletionPropagation propagationPolicy) { + return resource.withPropagationPolicy(propagationPolicy); + } + + @Override + public Watch watch(Watcher watcher) { + return resource.watch(watcher); + } + + @Override + public T patch(T item) { + return resource.patch(item); + } + + @Override + public T patchStatus(T item) { + return resource.patchStatus(item); + } + + @Override + public T edit(UnaryOperator function) { + return resource.edit(function); + } + + @Override + public T waitUntilReady(long amount, TimeUnit timeUnit) { + return resource.waitUntilReady(amount, timeUnit); + } + + @Override + public Watch watch(ListOptions options, Watcher watcher) { + return resource.watch(options, watcher); + } + + @Override + public T waitUntilCondition(Predicate condition, long amount, TimeUnit timeUnit) { + return resource.waitUntilCondition(condition, amount, timeUnit); + } + + @Override + public Waitable withWaitRetryBackoff(long initialBackoff, TimeUnit backoffUnit, double backoffMultiplier) { + return resource.withWaitRetryBackoff(initialBackoff, backoffUnit, backoffMultiplier); + } + + @Override + public Informable withIndexers(Map>> indexers) { + return resource.withIndexers(indexers); + } + + @Override + public WritableOperation dryRun(boolean isDryRun) { + return resource.dryRun(isDryRun); + } + + @Override + public T edit(Visitor... visitors) { + return resource.edit(visitors); + } + + @Override + public T patch(PatchContext patchContext, T item) { + return resource.patch(patchContext, item); + } + + @Override + public Informable withLimit(Long limit) { + return resource.withLimit(limit); + } + + @Override + public T edit(Class visitorType, Visitor visitor) { + return resource.edit(visitorType, visitor); + } + + @Override + public Watch watch(String resourceVersion, Watcher watcher) { + return resource.watch(resourceVersion, watcher); + } + + @Override + public T accept(Consumer function) { + return resource.accept(function); + } + + @Override + public SharedIndexInformer inform() { + return resource.inform(); + } + + @Override + public T patch(String patch) { + return resource.patch(patch); + } + + @Override + public T patch(PatchContext patchContext, String patch) { + return resource.patch(patchContext, patch); + } + + @Override + public SharedIndexInformer inform(ResourceEventHandler handler) { + return resource.inform(handler); + } + + @Override + public SharedIndexInformer inform(ResourceEventHandler handler, long resync) { + return resource.inform(handler, resync); + } + + @Override + public SharedIndexInformer runnableInformer(long resync) { + return resource.runnableInformer(resync); + } + + @Override + public CompletableFuture> informOnCondition(Predicate> condition) { + return resource.informOnCondition(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 ba5dfaea6cc..48ed1073162 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 @@ -51,6 +51,7 @@ import io.fabric8.kubernetes.client.informers.impl.DefaultSharedIndexInformer; import io.fabric8.kubernetes.client.readiness.Readiness; import io.fabric8.kubernetes.client.utils.CreateOrReplaceHelper; +import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; import io.fabric8.kubernetes.client.utils.Serialization; import io.fabric8.kubernetes.client.utils.URLUtils; import io.fabric8.kubernetes.client.utils.URLUtils.URLBuilder; @@ -518,7 +519,7 @@ public T patchStatus(T item) { @Override public R withItem(T item) { - return newResource(context.withItem(item)); + return newResource(context.withItem(item).withName(KubernetesResourceUtil.getName(item))); } void deleteThis() { diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/HasMetadataOperation.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/HasMetadataOperation.java index e269bf625de..988ae8b92e8 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/HasMetadataOperation.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/HasMetadataOperation.java @@ -41,8 +41,6 @@ import static io.fabric8.kubernetes.client.utils.IOHelpers.convertToJson; public class HasMetadataOperation, R extends Resource> extends BaseOperation< T, L, R> { - private static final String NO_BUILDER = "Cannot edit with visitors, no builder is associated"; - public static final DeletionPropagation DEFAULT_PROPAGATION_POLICY = DeletionPropagation.BACKGROUND; public static final long DEFAULT_GRACE_PERIOD_IN_SECONDS = -1L; private static final String PATCH_OPERATION = "patch"; @@ -89,10 +87,7 @@ public T accept(Consumer consumer) { protected > VisitableBuilder createVisitableBuilder(T item) { ResourceHandler handler = Handlers.get(item, new BaseClient(context)); - if (handler != null) { - return handler.edit(item); - } - throw new KubernetesClientException(NO_BUILDER); + return handler.edit(item); } @Override diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationSupport.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationSupport.java index 9d34fedb95d..0b429127f74 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationSupport.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/base/OperationSupport.java @@ -94,9 +94,9 @@ public OperationSupport(OperationContext ctx) { this.name = ctx.getName() ; this.apiGroupName = ctx.getApiGroupName(); this.dryRun = ctx.getDryRun(); - if (ctx.getApiGroupVersion() != null) { + if (Utils.isNotNullOrEmpty(ctx.getApiGroupVersion())) { this.apiGroupVersion = ctx.getApiGroupVersion(); - } else if (ctx.getConfig() != null) { + } else if (ctx.getConfig() != null && Utils.isNotNullOrEmpty(ctx.getConfig().getApiVersion())) { this.apiGroupVersion = ctx.getConfig().getApiVersion(); } else { this.apiGroupVersion = "v1"; diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java similarity index 88% rename from kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java rename to kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java index a0701795db0..0d879d20ae3 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package io.fabric8.kubernetes.client.dsl; +package io.fabric8.kubernetes.client.dsl.internal; + +import io.fabric8.kubernetes.client.dsl.Namespaceable; public interface NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable extends VisitFromServerGetWatchDeleteRecreateWaitApplicable, 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 cc821ee3125..86630f97839 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 @@ -33,10 +33,8 @@ import io.fabric8.kubernetes.client.dsl.CascadingDeletable; import io.fabric8.kubernetes.client.dsl.Deletable; 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.VisitFromServerWritable; import io.fabric8.kubernetes.client.dsl.Waitable; import io.fabric8.kubernetes.client.dsl.base.HasMetadataOperation; @@ -255,11 +253,7 @@ static HasMetadata acceptVisitors(HasMetadata item, List visitors, Stri } static > ResourceHandler handlerOf(T item, OperationContext context) { - ResourceHandler result = Handlers.get(item, new BaseClient(context)); - if (result == null) { - throw new KubernetesClientException("Could not find a registered handler for item: [" + item + "]."); - } - return result; + return Handlers.get(item, new BaseClient(context)); } } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java similarity index 82% rename from kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java rename to kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java index 3d8de70496c..2b6d53ab093 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/dsl/internal/VisitFromServerGetWatchDeleteRecreateWaitApplicable.java @@ -14,13 +14,19 @@ * limitations under the License. */ -package io.fabric8.kubernetes.client.dsl; +package io.fabric8.kubernetes.client.dsl.internal; import io.fabric8.kubernetes.api.builder.TypedVisitor; import io.fabric8.kubernetes.api.builder.Visitable; import io.fabric8.kubernetes.api.builder.Visitor; import io.fabric8.kubernetes.client.FromServerGettable; import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.dsl.DryRunable; +import io.fabric8.kubernetes.client.dsl.Editable; +import io.fabric8.kubernetes.client.dsl.Readiable; +import io.fabric8.kubernetes.client.dsl.VisitFromServerWritable; +import io.fabric8.kubernetes.client.dsl.Waitable; +import io.fabric8.kubernetes.client.dsl.Watchable; public interface VisitFromServerGetWatchDeleteRecreateWaitApplicable extends Visitable>, FromServerGettable, diff --git a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java index 19b4f743787..26796e6d7f3 100644 --- a/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java +++ b/kubernetes-client/src/main/java/io/fabric8/kubernetes/client/osgi/ManagedKubernetesClient.java @@ -50,27 +50,26 @@ import io.fabric8.kubernetes.api.model.ServiceAccount; import io.fabric8.kubernetes.api.model.ServiceAccountList; import io.fabric8.kubernetes.api.model.ServiceList; +import io.fabric8.kubernetes.api.model.authentication.TokenReview; import io.fabric8.kubernetes.api.model.certificates.v1beta1.CertificateSigningRequest; import io.fabric8.kubernetes.api.model.certificates.v1beta1.CertificateSigningRequestList; -import io.fabric8.kubernetes.api.model.authentication.TokenReview; import io.fabric8.kubernetes.api.model.coordination.v1.Lease; import io.fabric8.kubernetes.api.model.coordination.v1.LeaseList; import io.fabric8.kubernetes.api.model.node.v1beta1.RuntimeClass; import io.fabric8.kubernetes.api.model.node.v1beta1.RuntimeClassList; import io.fabric8.kubernetes.client.Adapters; import io.fabric8.kubernetes.client.AdmissionRegistrationAPIGroupDSL; +import io.fabric8.kubernetes.client.BaseClient; import io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.ConfigBuilder; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.client.DefaultKubernetesClient; +import io.fabric8.kubernetes.client.ExtensionAdapter; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.NamespacedKubernetesClient; import io.fabric8.kubernetes.client.OAuthTokenProvider; -import io.fabric8.kubernetes.client.ExtensionAdapter; -import io.fabric8.kubernetes.client.BaseClient; -import io.fabric8.kubernetes.client.DefaultKubernetesClient; -import io.fabric8.kubernetes.client.ResourceHandler; import io.fabric8.kubernetes.client.RequestConfig; -import io.fabric8.kubernetes.client.Handlers; +import io.fabric8.kubernetes.client.ResourceHandler; import io.fabric8.kubernetes.client.VersionInfo; import io.fabric8.kubernetes.client.dsl.ApiextensionsAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.AppsAPIGroupDSL; @@ -88,7 +87,7 @@ import io.fabric8.kubernetes.client.dsl.MetricAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; @@ -101,7 +100,6 @@ import io.fabric8.kubernetes.client.dsl.ServiceResource; import io.fabric8.kubernetes.client.dsl.StorageAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.V1APIGroupDSL; -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext; import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectorBuilder; import io.fabric8.kubernetes.client.extended.run.RunConfigBuilder; @@ -125,7 +123,32 @@ import java.util.Map; import java.util.concurrent.ExecutorService; -import static io.fabric8.kubernetes.client.Config.*; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_API_VERSION_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_AUTH_BASIC_PASSWORD_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_AUTH_BASIC_USERNAME_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CA_CERTIFICATE_DATA_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CA_CERTIFICATE_FILE_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_CERTIFICATE_DATA_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_CERTIFICATE_FILE_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_KEY_ALGO_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_KEY_DATA_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_KEY_FILE_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_CLIENT_KEY_PASSPHRASE_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_HTTPS_PROXY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_HTTP_PROXY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_KEYSTORE_FILE_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_KEYSTORE_PASSPHRASE_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_MASTER_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_NO_PROXY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_OAUTH_TOKEN_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_REQUEST_TIMEOUT_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_TRUSTSTORE_FILE_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_TRUSTSTORE_PASSPHRASE_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_WATCH_RECONNECT_INTERVAL_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_WATCH_RECONNECT_LIMIT_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_WEBSOCKET_PING_INTERVAL_SYSTEM_PROPERTY; +import static io.fabric8.kubernetes.client.Config.KUBERNETES_WEBSOCKET_TIMEOUT_SYSTEM_PROPERTY; @Component(immediate = true, configurationPid = "io.fabric8.kubernetes.client", policy = ConfigurationPolicy.REQUIRE) @Service({KubernetesClient.class,NamespacedKubernetesClient.class}) @@ -267,12 +290,12 @@ public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resource(HasMetadata is) { + public NamespaceableResource resource(HasMetadata is) { return delegate.resource(is); } @Override - public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(String s) { + public NamespaceableResource resource(String s) { return delegate.resource(s); } diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/GenericResourceIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/GenericResourceIT.java index bc1482782fa..33aa7e80c12 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/GenericResourceIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/GenericResourceIT.java @@ -28,7 +28,7 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaPropsBuilder; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.clnt.v4_0.utils.Serialization; import org.arquillian.cube.kubernetes.api.Session; @@ -71,7 +71,7 @@ public void testGenericBuiltinResourceWithoutMetadata() { configMap.setKind("ConfigMap"); configMap.setApiVersion("v1"); configMap.setMetadata(new ObjectMetaBuilder().withName("my-map").build()); - NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource = client.resource(configMap); + NamespaceableResource resource = client.resource(configMap); GenericKubernetesResource result = resource.createOrReplace(); assertNotNull(result); @@ -93,7 +93,7 @@ public void testGenericCustomResourceWithoutMetadata() { itest.setApiVersion("examples.fabric8.io/v1"); itest.setMetadata(new ObjectMetaBuilder().withName("my-itest").build()); - NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource = client.resource(itest); + NamespaceableResource resource = client.resource(itest); GenericKubernetesResource result = resource.createOrReplace(); assertNotNull(result); diff --git a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java index f8d8d317d62..0fbf7c1c6b5 100644 --- a/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java +++ b/kubernetes-itests/src/test/java/io/fabric8/kubernetes/ResourceIT.java @@ -37,6 +37,7 @@ 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.Utils; import org.arquillian.cube.kubernetes.api.Session; import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes; @@ -171,7 +172,8 @@ public void delete() { @Test public void testDeleteExistingWithOrphanDeletion() throws Exception { // Create Deployment - client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); + Resource resource = client.resource(deployment).inNamespace(session.getNamespace()); + resource.createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); // get uid of underlying replicaset. we expect this NOT to match later, meaning the orphan WAS deleted. @@ -179,8 +181,9 @@ public void testDeleteExistingWithOrphanDeletion() throws Exception { assertEquals(1, replicaSetList.getItems().size()); String replicaSetUid = replicaSetList.getItems().get(0).getMetadata().getUid(); - // Recreate deployment with deleteExisting - client.resource(deployment).inNamespace(session.getNamespace()).deletingExisting().createOrReplace(); + // Recreate deployment + resource.delete(); + resource.createOrReplace(); final Callable> replicaSets = () -> client.apps().replicaSets() .inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().stream() .filter(rs -> Utils.isNullOrEmpty(rs.getMetadata().getDeletionTimestamp())) @@ -191,7 +194,7 @@ public void testDeleteExistingWithOrphanDeletion() throws Exception { assertNotEquals(replicaSetUid, replicaSets.call().iterator().next().getMetadata().getUid()); // cleanup - assertEquals(true, client.resource(deployment).inNamespace(session.getNamespace()).withGracePeriod(0L).delete()); + assertEquals(true, resource.withGracePeriod(0L).delete()); // Check whether child resources are also deleted await().atMost(30, TimeUnit.SECONDS) .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().isEmpty()); @@ -200,7 +203,9 @@ public void testDeleteExistingWithOrphanDeletion() throws Exception { @Test public void testDeleteExistingWithoutOrphanDeletion() { // Create Deployment - client.resource(deployment).inNamespace(session.getNamespace()).createOrReplace(); + Resource resource = client.resource(deployment) + .inNamespace(session.getNamespace()); + resource.createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); // get uid of underlying replicaset. we expect this to match later, meaning the orphan was not deleted. @@ -208,12 +213,11 @@ public void testDeleteExistingWithoutOrphanDeletion() { assertEquals(1, replicaSetList.getItems().size()); String replicaSetUid= replicaSetList.getItems().get(0).getMetadata().getUid(); - // Recreate deployment with deleteExisting - client.resource(deployment) - .inNamespace(session.getNamespace()) + // Recreate deployment + resource .withPropagationPolicy(DeletionPropagation.ORPHAN) - .deletingExisting() - .createOrReplace(); + .delete(); + resource.createOrReplace(); await().atMost(30, TimeUnit.SECONDS).until(resourceIsReady(deployment)); @@ -223,7 +227,7 @@ public void testDeleteExistingWithoutOrphanDeletion() { assertEquals(replicaSetUid, replicaSetList.getItems().get(0).getMetadata().getUid()); // cleanup - assertEquals(true, client.resource(deployment).inNamespace(session.getNamespace()).delete()); + assertEquals(true, resource.delete()); // Check whether child resources are also deleted await().atMost(30, TimeUnit.SECONDS) .until(() -> client.apps().replicaSets().inNamespace(session.getNamespace()).withLabel("run", deploymentName).list().getItems().size() == 0); diff --git a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CreateOrReplaceResourceTest.java b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CreateOrReplaceResourceTest.java index a3c8c5499d8..7769acf6abb 100644 --- a/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CreateOrReplaceResourceTest.java +++ b/kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/CreateOrReplaceResourceTest.java @@ -27,7 +27,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.dsl.MixedOperation; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.PodResource; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; @@ -85,7 +85,7 @@ void testResourceCreateFailure() { // Given server.expect().post().withPath("/api/v1/namespaces/test/pods").andReturn(HttpURLConnection.HTTP_BAD_REQUEST, new PodBuilder() .withNewMetadata().withResourceVersion("12345").endMetadata().build()).once(); - NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable podOperation = client.resource(new PodBuilder().withNewMetadata().withName("pod123").endMetadata().build()); + NamespaceableResource podOperation = client.resource(new PodBuilder().withNewMetadata().withName("pod123").endMetadata().build()); // When assertThrows(KubernetesClientException.class, podOperation::createOrReplace); 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 db993dff67c..22eee6aed4e 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 @@ -32,9 +32,9 @@ import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.WatcherException; -import io.fabric8.kubernetes.client.dsl.Applicable; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.PodResource; +import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.readiness.Readiness; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; @@ -78,7 +78,7 @@ void testCreateOrReplace() { // Then assertEquals(pod1, response); } - + @Test void testCreateOrReplaceString() { // Given @@ -106,7 +106,7 @@ void testCreateOrReplaceWhenCreateFails() { Pod pod1 = new PodBuilder().withNewMetadata().withName("pod1").withNamespace("test").and().build(); server.expect().post().withPath("/api/v1/namespaces/test/pods").andReturn(HttpURLConnection.HTTP_BAD_REQUEST, pod1).once(); - NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable podOperation = client.resource(pod1); + NamespaceableResource podOperation = client.resource(pod1); // When assertThrows(KubernetesClientException.class, podOperation::createOrReplace); @@ -129,7 +129,9 @@ void testCreateOrReplaceWithDeleteExisting() throws Exception { server.expect().delete().withPath("/api/v1/namespaces/ns1/pods/pod1").andReturn(HttpURLConnection.HTTP_OK, pod1).once(); server.expect().post().withPath("/api/v1/namespaces/ns1/pods").andReturn(HttpURLConnection.HTTP_CREATED, pod1).once(); - HasMetadata response = client.resource(pod1).inNamespace("ns1").deletingExisting().createOrReplace(); + Resource resource = client.resource(pod1).inNamespace("ns1"); + resource.delete(); + HasMetadata response = resource.createOrReplace(); assertEquals(pod1, response); RecordedRequest request = server.getLastRequest(); @@ -145,7 +147,9 @@ void itPassesPropagationPolicyWithDeleteExisting() throws InterruptedException { server.expect().delete().withPath("/api/v1/namespaces/ns1/pods/pod1").andReturn(HttpURLConnection.HTTP_OK, pod1).once(); server.expect().post().withPath("/api/v1/namespaces/ns1/pods").andReturn(HttpURLConnection.HTTP_CREATED, pod1).once(); - HasMetadata response = client.resource(pod1).inNamespace("ns1").withPropagationPolicy(DeletionPropagation.FOREGROUND).deletingExisting().createOrReplace(); + Resource resource = client.resource(pod1).inNamespace("ns1"); + resource.withPropagationPolicy(DeletionPropagation.FOREGROUND).delete(); + HasMetadata response = resource.createOrReplace(); assertEquals(pod1, response); assertEquals(2, server.getRequestCount()); @@ -168,8 +172,8 @@ void testCreateOrReplaceWithDeleteExistingWithCreateFailed() { server.expect().post().withPath("/api/v1/namespaces/ns1/pods").andReturn(HttpURLConnection.HTTP_CONFLICT, pod1).once(); server.expect().delete().withPath("/api/v1/namespaces/ns1/pods/pod1").andReturn(HttpURLConnection.HTTP_OK, pod1).once(); server.expect().post().withPath("/api/v1/namespaces/ns1/pods").andReturn(HttpURLConnection.HTTP_BAD_REQUEST, pod1).once(); - Applicable podOperation = client.resource(pod1).inNamespace("ns1").deletingExisting(); - + Resource podOperation = client.resource(pod1).inNamespace("ns1"); + podOperation.delete(); // When assertThrows(KubernetesClientException.class, podOperation::createOrReplace); } @@ -506,7 +510,9 @@ void testCreateAndWaitUntilReady() throws InterruptedException { .always(); - Pod p = client.resource(noReady).createOrReplaceAnd().waitUntilReady(10, SECONDS); + NamespaceableResource resource = client.resource(noReady); + resource.create(); + Pod p = resource.waitUntilReady(10, SECONDS); Assert.assertTrue(Readiness.isPodReady(p)); } diff --git a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java index b2198ec4fc7..031eb9629c5 100644 --- a/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java +++ b/openshift-client/src/main/java/io/fabric8/openshift/client/osgi/ManagedOpenShiftClient.java @@ -84,8 +84,8 @@ import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Nameable; import io.fabric8.kubernetes.client.dsl.NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable; -import io.fabric8.kubernetes.client.dsl.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable; import io.fabric8.kubernetes.client.dsl.Namespaceable; +import io.fabric8.kubernetes.client.dsl.NamespaceableResource; import io.fabric8.kubernetes.client.dsl.NamespacedInOutCreateable; import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL; import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; @@ -610,13 +610,13 @@ public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable resource(HasMetadata item) { - return delegate.resource(item); + public NamespaceableResource resource(String s) { + return delegate.resource(s); } @Override - public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable resource(String s) { - return delegate.resource(s); + public NamespaceableResource resource(T is) { + return delegate.resource(is); } @Override