Skip to content

Commit

Permalink
refactor: add putOrRemove to DefaultManagedDependentResourceContext
Browse files Browse the repository at this point in the history
The javadoc of the existing put method states that it returns Optional.
The implementation also returns Optional, but the method signature
declares it returns T. Meaning the caller has to cast it to Optional
to get at the return value.

This new method will supercede the existing put method

Signed-off-by: Robert Young <robeyoun@redhat.com>
  • Loading branch information
robobario committed Nov 19, 2024
1 parent 204ac34 commit d492ff6
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ public <T> T put(Object key, T value) {
return (T) Optional.ofNullable(attributes.put(key, value));
}

@Override
@SuppressWarnings("unchecked")
public <T> Optional<T> putOrRemove(Object key, T value) {
if (value == null) {
return (Optional<T>) Optional.ofNullable(attributes.remove(key));
}
return (Optional<T>) Optional.ofNullable(attributes.put(key, value));
}

@Override
@SuppressWarnings("unused")
public <T> T getMandatory(Object key, Class<T> expectedType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ public interface ManagedDependentResourceContext {
@SuppressWarnings("unchecked")
<T> T put(Object key, T value);

/**
* Associates the specified contextual value to the specified key. If the value is {@code null},
* the semantics of this operation is defined as removing the mapping associated with the
* specified key.
*
* @param <T> object type
* @param key the key identifying which contextual object to add or remove from the context
* @param value the value to add to the context or {@code null} to remove an existing entry
* associated with the specified key
* @return an Optional containing the previous value associated with the key or
* {@link Optional#empty()} if none existed
*/
@SuppressWarnings("unchecked")
<T> Optional<T> putOrRemove(Object key, T value);

/**
* Retrieves the value associated with the key or fail with an exception if none exists.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,84 +1,117 @@
package io.javaoperatorsdk.operator.api.reconciler.dependent.managed;

import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.junit.jupiter.api.Test;

import io.javaoperatorsdk.operator.processing.dependent.workflow.WorkflowReconcileResult;

import static io.javaoperatorsdk.operator.api.reconciler.dependent.managed.DefaultManagedDependentResourceContext.RECONCILE_RESULT_KEY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class DefaultManagedDependentResourceContextTest {

private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext();

@Test
void getWhenEmpty() {
Optional<String> actual = context.get("key", String.class);
assertThat(actual).isEmpty();
}

@Test
void get() {
context.put("key", "value");
Optional<String> actual = context.get("key", String.class);
assertThat(actual).contains("value");
}

@Test
void putNewValueOverwrites() {
context.put("key", "value");
context.put("key", "valueB");
Optional<String> actual = context.get("key", String.class);
assertThat(actual).contains("valueB");
}

@Test
void putNewValueReturnsPriorValue() {
context.put("key", "value");
Optional<String> actual = (Optional<String>) (Object)context.put("key", "valueB");
assertThat(actual).contains("value");
}

@Test
void putNullRemoves() {
context.put("key", "value");
context.put("key", null);
Optional<String> actual = context.get("key", String.class);
assertThat(actual).isEmpty();
}

@Test
void putNullReturnsPriorValue() {
context.put("key", "value");
Optional<String> actual = context.put("key", null);
assertThat(actual).contains("value");
}

@Test
void getMandatory() {
context.put("key", "value");
String actual = context.getMandatory("key", String.class);
assertThat(actual).isEqualTo("value");
}

@Test
void getMandatoryWhenEmpty() {
assertThatThrownBy(() -> {
context.getMandatory("key", String.class);
}).isInstanceOf(IllegalStateException.class)
.hasMessage("Mandatory attribute (key: key, type: java.lang.String) is missing or not of the expected type");
}

@Test
void getWorkflowReconcileResult() {
WorkflowReconcileResult result = new WorkflowReconcileResult(List.of(), List.of(), Map.of(), Map.of());
context.put(RECONCILE_RESULT_KEY, result);
Optional<WorkflowReconcileResult> actual = context.getWorkflowReconcileResult();
assertThat(actual).containsSame(result);
}

}
private ManagedDependentResourceContext context = new DefaultManagedDependentResourceContext();

@Test
void getWhenEmpty() {
Optional<String> actual = context.get("key", String.class);
assertThat(actual).isEmpty();
}

@Test
void get() {
context.put("key", "value");
Optional<String> actual = context.get("key", String.class);
assertThat(actual).contains("value");
}

@Test
void putNewValueOverwrites() {
context.put("key", "value");
context.put("key", "valueB");
Optional<String> actual = context.get("key", String.class);
assertThat(actual).contains("valueB");
}

@Test
void putOrRemoveNewValueOverwrites() {
context.putOrRemove("key", "value");
context.putOrRemove("key", "valueB");
Optional<String> actual = context.get("key", String.class);
assertThat(actual).contains("valueB");
}

@Test
void putNewValueReturnsPriorValue() {
context.put("key", "value");
Optional<String> actual = (Optional<String>) (Object) context.put("key", "valueB");
assertThat(actual).contains("value");
}

@Test
void putOrRemoveNewValueReturnsPriorValue() {
context.put("key", "value");
Optional<String> actual = context.putOrRemove("key", "valueB");
assertThat(actual).contains("value");
}

@Test
void putNullRemoves() {
context.put("key", "value");
context.put("key", null);
Optional<String> actual = context.get("key", String.class);
assertThat(actual).isEmpty();
}

@Test
void putOrRemoveNullRemoves() {
context.putOrRemove("key", "value");
context.putOrRemove("key", null);
Optional<String> actual = context.get("key", String.class);
assertThat(actual).isEmpty();
}

@Test
void putNullReturnsPriorValue() {
context.put("key", "value");
Optional<String> actual = context.put("key", null);
assertThat(actual).contains("value");
}

@Test
void putOrRemoveNullReturnsPriorValue() {
context.putOrRemove("key", "value");
Optional<String> actual = context.putOrRemove("key", null);
assertThat(actual).contains("value");
}

@Test
void getMandatory() {
context.put("key", "value");
String actual = context.getMandatory("key", String.class);
assertThat(actual).isEqualTo("value");
}

@Test
void getMandatoryWhenEmpty() {
assertThatThrownBy(() -> {
context.getMandatory("key", String.class);
}).isInstanceOf(IllegalStateException.class)
.hasMessage(
"Mandatory attribute (key: key, type: java.lang.String) is missing or not of the expected type");
}

@Test
void getWorkflowReconcileResult() {
WorkflowReconcileResult result =
new WorkflowReconcileResult(List.of(), List.of(), Map.of(), Map.of());
context.put(RECONCILE_RESULT_KEY, result);
Optional<WorkflowReconcileResult> actual = context.getWorkflowReconcileResult();
assertThat(actual).containsSame(result);
}

}

0 comments on commit d492ff6

Please sign in to comment.