Skip to content

Commit

Permalink
Change Placeholder interface to resolve to a List of Strings instead of
Browse files Browse the repository at this point in the history
a single String

* Required for JwtPlaceholder to work with this new architecture

Signed-off-by: Yannic Klem <Yannic.Klem@bosch.io>
  • Loading branch information
Yannic92 committed Mar 3, 2022
1 parent b4f437f commit 943405a
Show file tree
Hide file tree
Showing 32 changed files with 133 additions and 140 deletions.
Expand Up @@ -44,16 +44,16 @@ public boolean supports(final String name) {
return SUPPORTED.contains(name);
}

protected Optional<String> doResolve(final T entityId, final String placeholder) {
protected List<String> doResolve(final T entityId, final String placeholder) {
switch (placeholder) {
case NAMESPACE_PLACEHOLDER:
return Optional.of(entityId.getNamespace());
return Collections.singletonList(entityId.getNamespace());
case NAME_PLACEHOLDER:
return Optional.of(entityId.getName());
return Collections.singletonList(entityId.getName());
case ID_PLACEHOLDER:
return Optional.of(entityId.toString());
return Collections.singletonList(entityId.toString());
default:
return Optional.empty();
return Collections.emptyList();
}
}

Expand Down
Expand Up @@ -17,7 +17,6 @@

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.annotation.concurrent.Immutable;

Expand Down Expand Up @@ -56,13 +55,13 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final ConnectionId connectionId, final String placeholder) {
public List<String> resolve(final ConnectionId connectionId, final String placeholder) {
argumentNotEmpty(placeholder, "placeholder");
checkNotNull(connectionId, "Connection ID");
if (ID_PLACEHOLDER.equals(placeholder)) {
return Optional.of(connectionId.toString());
return Collections.singletonList(connectionId.toString());
}
return Optional.empty();
return Collections.emptyList();
}

}
Expand Up @@ -15,6 +15,8 @@
import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty;
import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.annotation.concurrent.Immutable;
Expand All @@ -41,15 +43,15 @@ public String getPrefix() {
}

@Override
public Optional<String> resolve(final EntityId entityId, final String placeholder) {
public List<String> resolve(final EntityId entityId, final String placeholder) {
argumentNotEmpty(placeholder, "placeholder");
checkNotNull(entityId, "Entity ID");
try {
final NamespacedEntityId namespacedEntityId = NamespacedEntityId.of(entityId.getEntityType(), entityId);
return doResolve(namespacedEntityId, placeholder);
} catch (final NamespacedEntityIdInvalidException e) {
// not a namespaced entity ID; does not resolve.
return Optional.empty();
return Collections.emptyList();
}
}
}
Expand Up @@ -40,13 +40,13 @@ final class ImmutableFeaturePlaceholder implements FeaturePlaceholder {
static final ImmutableFeaturePlaceholder INSTANCE = new ImmutableFeaturePlaceholder();

@Override
public Optional<String> resolve(final CharSequence featureId, final String placeholder) {
public List<String> resolve(final CharSequence featureId, final String placeholder) {
checkNotNull(featureId, "featureId");
argumentNotEmpty(placeholder, "placeholder");
if (ID_PLACEHOLDER.equals(placeholder)) {
return Optional.of(featureId.toString());
return Collections.singletonList(featureId.toString());
}
return Optional.empty();
return Collections.emptyList();
}

@Override
Expand Down
Expand Up @@ -15,6 +15,8 @@
import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty;
import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.annotation.concurrent.Immutable;
Expand All @@ -40,13 +42,13 @@ public String getPrefix() {
}

@Override
public Optional<String> resolve(final EntityId policyId, final String placeholder) {
public List<String> resolve(final EntityId policyId, final String placeholder) {
argumentNotEmpty(placeholder, "placeholder");
checkNotNull(policyId, "Policy ID");
if (policyId instanceof PolicyId) {
return doResolve(((PolicyId) policyId), placeholder);
} else {
return Optional.empty();
return Collections.emptyList();
}
}
}
Expand Up @@ -56,14 +56,16 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(@Nullable final AuthorizationContext authorizationContext, final String headerKey) {
public List<String> resolve(@Nullable final AuthorizationContext authorizationContext, final String headerKey) {
// precondition: supports(headerKey)
return Optional.ofNullable(authorizationContext)
.flatMap(context -> context.getAuthorizationSubjects()
.stream()
.map(AuthorizationSubject::getId)
.findFirst()
);
)//TODO: Yannic maybe we can return the full list instead of just the first?
.map(Collections::singletonList)
.orElseGet(Collections::emptyList);
}

@Override
Expand Down
Expand Up @@ -51,8 +51,8 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final String input, final String name) {
return supports(name) ? Optional.of(input) : Optional.empty();
public List<String> resolve(final String input, final String name) {
return supports(name) ? Collections.singletonList(input) : Collections.emptyList();
}

private ImmutableSourceAddressPlaceholder() {
Expand Down
Expand Up @@ -15,6 +15,8 @@
import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty;
import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

import javax.annotation.concurrent.Immutable;
Expand All @@ -40,13 +42,13 @@ public String getPrefix() {
}

@Override
public Optional<String> resolve(final EntityId thingId, final String placeholder) {
public List<String> resolve(final EntityId thingId, final String placeholder) {
argumentNotEmpty(placeholder, "placeholder");
checkNotNull(thingId, "Thing ID");
if (thingId instanceof ThingId) {
return doResolve(((ThingId) thingId), placeholder);
} else {
return Optional.empty();
return Collections.emptyList();
}
}
}
Expand Up @@ -48,7 +48,7 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final String placeholderSource, final String name) {
return supports(name) ? Optional.of(placeholderSource) : Optional.empty();
public List<String> resolve(final String placeholderSource, final String name) {
return supports(name) ? Collections.singletonList(placeholderSource) : Collections.emptyList();
}
}
Expand Up @@ -48,6 +48,6 @@ public void testPlaceholderResolver() {
ConnectivityPlaceholders.newConnectionIdPlaceholder(), connectionId);

assertThat(underTest.resolve("id"))
.contains(connectionId.toString());
.containsExactly(connectionId.toString());
}
}
Expand Up @@ -46,13 +46,13 @@ public void supports() {
@Test
public void resolve() {
final String expectedResolvingResult = "myTestId";
final Optional<String> result = underTest.resolve(ConnectionId.of(expectedResolvingResult), "id");
assertThat(result).contains(expectedResolvingResult);
final List<String> result = underTest.resolve(ConnectionId.of(expectedResolvingResult), "id");
assertThat(result).containsExactly(expectedResolvingResult);
}

@Test
public void resolveWithUnsupportedPlaceholder() {
final Optional<String> result = underTest.resolve(ConnectionId.of("myTestId"), "unsupported");
final List<String> result = underTest.resolve(ConnectionId.of("myTestId"), "unsupported");
assertThat(result).isEmpty();
}

Expand Down
Expand Up @@ -66,19 +66,19 @@ public void testPlaceholderResolver() {
ConnectivityPlaceholders.newTopicPathPlaceholder(), topic);

assertThat(underTest.resolve("full"))
.contains(fullPath);
.containsExactly(fullPath);
assertThat(underTest.resolve("namespace"))
.contains("org.eclipse.ditto");
.containsExactly("org.eclipse.ditto");
assertThat(underTest.resolve("entityName"))
.contains("foo23");
.containsExactly("foo23");
assertThat(underTest.resolve("group"))
.contains("things");
.containsExactly("things");
assertThat(underTest.resolve("channel"))
.contains("twin");
.containsExactly("twin");
assertThat(underTest.resolve("criterion"))
.contains("commands");
.containsExactly("commands");
assertThat(underTest.resolve("action"))
.contains("modify");
.containsExactly("modify");
}

@Test
Expand Down
Expand Up @@ -185,7 +185,7 @@ private Mqtt3HeaderPlaceholder() {
}

@Override
public Optional<String> resolve(final String placeholderSource, final String name) {
public List<String> resolve(final String placeholderSource, final String name) {
throw new UnsupportedOperationException("This placeholder is only used for validation and does not " +
"resolve the placeholder.");
}
Expand Down
Expand Up @@ -20,7 +20,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
Expand Down Expand Up @@ -477,8 +476,8 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final String placeholderSource, final String name) {
return Optional.of(placeholderSource);
public List<String> resolve(final String placeholderSource, final String name) {
return Collections.singletonList(placeholderSource);
}

}
Expand Down
Expand Up @@ -15,8 +15,10 @@
import static org.eclipse.ditto.base.model.common.ConditionChecker.argumentNotEmpty;
import static org.eclipse.ditto.base.model.common.ConditionChecker.checkNotNull;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.eclipse.ditto.json.JsonValue;
import org.eclipse.ditto.jwt.model.JsonWebToken;
Expand Down Expand Up @@ -59,10 +61,18 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final JsonWebToken jwt, final String placeholder) {
public List<String> resolve(final JsonWebToken jwt, final String placeholder) {
argumentNotEmpty(placeholder, "placeholder");
checkNotNull(jwt, "jwt");
return jwt.getBody().getValue(placeholder).map(JsonValue::formatAsString);
final Optional<JsonValue> value = jwt.getBody().getValue(placeholder);
return value.filter(JsonValue::isArray)
.map(JsonValue::asArray)
.map(array -> array.stream()
.map(JsonValue::formatAsString)
.collect(Collectors.toList()))
.or(() -> value.map(JsonValue::formatAsString)
.map(Collections::singletonList))
.orElseGet(Collections::emptyList);
}

}
Expand Up @@ -269,10 +269,10 @@ public void assertComplexFunctionWithTextWorks() {

assertThat(authSubjects).containsExactly(
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-some-audience-ope-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-other-ope-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-audience-ope-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-some-audience-all-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-other-ope-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-other-all-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-audience-ope-test"),
AuthorizationSubject.newInstance(subjectIssuer + ":" + "rest-audience-all-test")
);
}
Expand Down
Expand Up @@ -106,7 +106,7 @@ private PipelineElement resolveSinglePlaceholder(final String placeholderInPipel

if (placeholderReplacementInValidation == null) {
// normal mode
final List<String> resolvedValues = resolverPair.getKey().resolveValues(resolverPair.getValue());
final List<String> resolvedValues = resolverPair.getKey().resolve(resolverPair.getValue());
return resolvedValues.size() > 0 ? PipelineElement.resolved(resolvedValues) : PipelineElement.unresolved();
} else {
// validation mode: all placeholders resolve to dummy value.
Expand Down
Expand Up @@ -53,10 +53,12 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final Map<String, String> headers, final String headerKey) {
public List<String> resolve(final Map<String, String> headers, final String headerKey) {
ConditionChecker.argumentNotEmpty(headerKey, "headerKey");
ConditionChecker.argumentNotNull(headers, "headers");
return Optional.ofNullable(headers.get(headerKey));
return Optional.ofNullable(headers.get(headerKey))
.map(Collections::singletonList)
.orElseGet(Collections::emptyList);
}

@Override
Expand Down
Expand Up @@ -16,7 +16,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.annotation.concurrent.Immutable;

Expand All @@ -34,18 +33,13 @@ final class ImmutablePlaceholderResolver<T> implements PlaceholderResolver<T> {
this.placeholderSource = Collections.unmodifiableList(new ArrayList<>(placeholderSource));
}

@Override
public Optional<T> getPlaceholderSource() {
return placeholderSource.stream().findFirst();
}

@Override
public List<T> getPlaceholderSources() {
return placeholderSource;
}

@Override
public Optional<String> resolve(final T placeholderSource, final String name) {
public List<String> resolve(final T placeholderSource, final String name) {
return placeholder.resolve(placeholderSource, name);
}

Expand Down
Expand Up @@ -65,15 +65,15 @@ public boolean supports(final String name) {
}

@Override
public Optional<String> resolve(final Object someObject, final String placeholder) {
public List<String> resolve(final Object someObject, final String placeholder) {
ConditionChecker.argumentNotEmpty(placeholder, "placeholder");
switch (placeholder) {
case NOW_PLACEHOLDER:
return Optional.of(Instant.now().toString());
return Collections.singletonList(Instant.now().toString());
case NOW_EPOCH_MILLIS_PLACEHOLDER:
return Optional.of(String.valueOf(Instant.now().toEpochMilli()));
return Collections.singletonList(String.valueOf(Instant.now().toEpochMilli()));
default:
return Optional.empty();
return Collections.emptyList();
}
}

Expand Down

0 comments on commit 943405a

Please sign in to comment.