Skip to content

Commit

Permalink
feat: add factory methods to help with SSA
Browse files Browse the repository at this point in the history
Fixes #6012
  • Loading branch information
metacosm committed May 17, 2024
1 parent 522e795 commit 02f3589
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Fix #5867: (java-generator) Add JsonFormat shape to date-time
* Fix #5954: (crd-generator) Sort required properties to ensure deterministic output
* Fix #5973: CacheImpl locking for reading indexes (Cache.byIndex|indexKeys|index) was reduced
* Fix #6012: Add emptyClusterWideCopyOf and emptyCopyOf methods on HasMetadata

#### Dependency Upgrade
* Fix #5695: Upgrade Fabric8 Kubernetes Model to Kubernetes v1.30.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,5 +545,4 @@ private static void schedule(Supplier<CompletableFuture<?>> runner, long delay,
});
}, delay, unit));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public interface HasMetadata extends KubernetesResource {
Pattern FINALIZER_NAME_MATCHER = Pattern.compile(
"^((" + DNS_LABEL_REGEXP + "\\.)+" + DNS_LABEL_START + 2 + DNS_LABEL_END + ")/"
+ DNS_LABEL_REGEXP);
String REQUIRES_NON_NULL_METADATA = "requires non-null metadata";
String REQUIRES_NON_NULL_NAME = "requires non-null name";
String REQUIRES_NON_NULL_NAMESPACE = "requires non-null namespace";

ObjectMeta getMetadata();

Expand Down Expand Up @@ -493,4 +496,43 @@ default void removeOwnerReference(HasMetadata owner) {
default Optional<ObjectMeta> optionalMetadata() {
return Optional.ofNullable(getMetadata());
}

static <T extends HasMetadata & Namespaced> T emptyCopyOf(T original, Supplier<T> constructor) {
final T t = constructor.get();
final ObjectMeta metadata = Objects.requireNonNull(original.getMetadata(), REQUIRES_NON_NULL_METADATA);
final String name = Objects.requireNonNull(metadata.getName(), REQUIRES_NON_NULL_NAME);
final String ns = Objects.requireNonNull(metadata.getNamespace(), REQUIRES_NON_NULL_NAMESPACE);
t.setMetadata(new ObjectMetaBuilder()
.withName(name)
.withNamespace(ns)
.build());
return t;
}

static <T extends HasMetadata> T emptyClusterWideCopyOf(T original, Supplier<T> constructor) {
final T t = constructor.get();
final ObjectMeta metadata = Objects.requireNonNull(original.getMetadata(), REQUIRES_NON_NULL_METADATA);
final String name = Objects.requireNonNull(metadata.getName(), REQUIRES_NON_NULL_NAME);
t.setMetadata(new ObjectMetaBuilder()
.withName(name)
.build());
return t;
}

static <T extends HasMetadata> T initNameAndNamespaceFrom(T instanceToInit, HasMetadata original) {
Objects.requireNonNull(original);
return HasMetadata.initNameAndNamespaceFrom(instanceToInit, original.getMetadata());
}

static <T extends HasMetadata> T initNameAndNamespaceFrom(T instanceToInit, ObjectMeta original) {
Objects.requireNonNull(instanceToInit);
final ObjectMeta metadata = Objects.requireNonNull(original, REQUIRES_NON_NULL_METADATA);
ObjectMeta objectMeta = new ObjectMeta();
objectMeta.setName(Objects.requireNonNull(metadata.getName(), REQUIRES_NON_NULL_NAME));
if (instanceToInit instanceof Namespaced) {
objectMeta.setNamespace(Objects.requireNonNull(metadata.getNamespace(), REQUIRES_NON_NULL_NAMESPACE));
}
instanceToInit.setMetadata(objectMeta);
return instanceToInit;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@

import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;

class HasMetadataTest {
@Test
Expand Down Expand Up @@ -235,6 +230,108 @@ void addingOwnerReferenceToResourceInDifferentNamespaceShouldFail() {
assertThrows(IllegalArgumentException.class, () -> namespaced1.addOwnerReference(namespaced2));
}

@Test
void testInitNameAndNamespaceFromNamespacedResource() {
TestNamespacedHasMetadata original = new TestNamespacedHasMetadata();
ObjectMeta originalMetadata = new ObjectMetaBuilder()
.withName("testName")
.withNamespace("testNamespace")
.withGeneration(100000L)
.build();
original.setMetadata(originalMetadata);

TestNamespacedHasMetadata copy = HasMetadata.initNameAndNamespaceFrom(new TestNamespacedHasMetadata(), original);

final ObjectMeta metadata = copy.getMetadata();
assertEquals(originalMetadata.getName(), metadata.getName());
assertEquals(originalMetadata.getNamespace(), metadata.getNamespace());
assertNull(metadata.getGeneration());
}

@Test
void testInitNameAndNamespaceFromClusteredResource() {
TestHasMetadata original = new TestHasMetadata();
ObjectMeta originalMetadata = new ObjectMetaBuilder()
.withName("testName")
.withGeneration(100000L)
.build();
original.setMetadata(originalMetadata);

TestHasMetadata copy = HasMetadata.initNameAndNamespaceFrom(new TestHasMetadata(), original);

final ObjectMeta metadata = copy.getMetadata();
assertEquals(originalMetadata.getName(), metadata.getName());
assertNull(metadata.getNamespace());
assertNull(metadata.getGeneration());
}

@Test
void testInitNameAndNamespaceFromMetadata() {
ObjectMeta originalMetadata = new ObjectMetaBuilder()
.withName("testName")
.withNamespace("testNamespace")
.withGeneration(100000L)
.build();

TestHasMetadata copy = HasMetadata.initNameAndNamespaceFrom(new TestHasMetadata(), originalMetadata);

final ObjectMeta metadata = copy.getMetadata();
assertEquals(originalMetadata.getName(), metadata.getName());
assertNull(metadata.getNamespace());
assertNull(metadata.getGeneration());
}

@Test
void initNameAndNamespaceFromNullInstanceShouldFail() {
TestNamespacedHasMetadata original = new TestNamespacedHasMetadata();
assertThrows(NullPointerException.class, () -> HasMetadata.initNameAndNamespaceFrom(null, original));
}

@Test
void initNameAndNamespaceFromWithNullMetadataShouldFail() {
TestHasMetadata original = new TestHasMetadata();
original.setMetadata(null);

Exception exception = assertThrows(NullPointerException.class,
() -> HasMetadata.initNameAndNamespaceFrom(new TestHasMetadata(), original));
assertEquals(HasMetadata.REQUIRES_NON_NULL_METADATA, exception.getMessage());
}

@Test
void emptyClusterWideCopyOfWithMissingNameShouldFail() {
TestNamespacedHasMetadata original = new TestNamespacedHasMetadata();
ObjectMeta originalMetadata = new ObjectMetaBuilder()
.withNamespace("testNamespace")
.build();
original.setMetadata(originalMetadata);

Exception exception = assertThrows(NullPointerException.class,
() -> HasMetadata.initNameAndNamespaceFrom(new TestNamespacedHasMetadata(), original));
assertEquals(HasMetadata.REQUIRES_NON_NULL_NAME, exception.getMessage());
}

static class TestHasMetadata implements HasMetadata {
private ObjectMeta metadata;

@Override
public ObjectMeta getMetadata() {
return metadata;
}

@Override
public void setMetadata(ObjectMeta metadata) {
this.metadata = metadata;
}

@Override
public void setApiVersion(String version) {
}
}

static class TestNamespacedHasMetadata extends TestHasMetadata implements Namespaced {
// No additional fields or methods needed for this simple test implementation
}

@Group("fabric8.io")
@Version("v1")
private static class Woman implements HasMetadata {
Expand Down

0 comments on commit 02f3589

Please sign in to comment.