com.yahoo.security.tls.CapabilitySet Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.security.tls;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* @author bjorncs
*/
public class CapabilitySet implements ToCapabilitySet {
private static final Logger log = Logger.getLogger(CapabilitySet.class.getName());
private static final Map PREDEFINED = new HashMap<>();
/* Predefined capability sets */
public static final CapabilitySet ALL = predefined(
"vespa.all", Capability.values());
public static final CapabilitySet TELEMETRY = predefined(
"vespa.telemetry",
Capability.CONTENT__STATUS_PAGES, Capability.CONTENT__STATE_API, Capability.CONTENT__METRICS_API,
Capability.CONTAINER__STATE_API, Capability.METRICSPROXY__METRICS_API,
Capability.SENTINEL__CONNECTIVITY_CHECK);
private static final CapabilitySet SHARED_CAPABILITIES_APP_NODE = CapabilitySet.unionOf(List.of(
Capability.LOGSERVER_API, Capability.CONFIGSERVER__CONFIG_API,
Capability.CONFIGSERVER__FILEDISTRIBUTION_API, Capability.CONFIGPROXY__CONFIG_API,
Capability.CONFIGPROXY__FILEDISTRIBUTION_API, Capability.SLOBROK__API, TELEMETRY));
public static final CapabilitySet CONTENT_NODE = predefined(
"vespa.content_node",
Capability.CONTENT__STORAGE_API, Capability.CONTENT__DOCUMENT_API, Capability.CONTAINER__DOCUMENT_API,
SHARED_CAPABILITIES_APP_NODE);
public static final CapabilitySet CONTAINER_NODE = predefined(
"vespa.container_node",
Capability.CONTAINER__DOCUMENT_API, Capability.CONTENT__DOCUMENT_API, Capability.CONTENT__SEARCH_API,
SHARED_CAPABILITIES_APP_NODE);
public static final CapabilitySet CLUSTER_CONTROLLER_NODE = predefined(
"vespa.cluster_controller_node",
Capability.CONTENT__CLUSTER_CONTROLLER__INTERNAL_STATE_API,
Capability.CLIENT__SLOBROK_API, Capability.CONTAINER__DOCUMENT_API, SHARED_CAPABILITIES_APP_NODE);
public static final CapabilitySet LOGSERVER_NODE = predefined(
"vespa.logserver_node", SHARED_CAPABILITIES_APP_NODE);
public static final CapabilitySet CONFIGSERVER_NODE = predefined(
"vespa.config_server_node",
Capability.CLIENT__FILERECEIVER_API, Capability.CONTAINER__MANAGEMENT_API, Capability.SLOBROK__API,
Capability.CLUSTER_CONTROLLER__REINDEXING, Capability.CLUSTER_CONTROLLER__STATE, Capability.LOGSERVER_API,
TELEMETRY);
private static CapabilitySet predefined(String name, ToCapabilitySet... capabilities) {
var instance = CapabilitySet.unionOf(List.of(capabilities));
PREDEFINED.put(name, instance);
return instance;
}
private static final CapabilitySet ALL_CAPABILITIES = new CapabilitySet(EnumSet.allOf(Capability.class));
private static final CapabilitySet NO_CAPABILITIES = new CapabilitySet(EnumSet.noneOf(Capability.class));
private final EnumSet caps;
private CapabilitySet(EnumSet caps) { this.caps = caps; }
@Override public CapabilitySet toCapabilitySet() { return this; }
public static CapabilitySet fromNames(Collection names) {
EnumSet caps = EnumSet.noneOf(Capability.class);
for (String name : names) {
var predefinedSet = PREDEFINED.get(name);
var capability = Capability.fromName(name).orElse(null);
if (capability != null) caps.add(capability);
else if (predefinedSet != null) caps.addAll(predefinedSet.caps);
else log.warning("Cannot find capability or capability set with name '%s'".formatted(name));
}
return new CapabilitySet(caps);
}
public static CapabilitySet ofSets(Collection capSets) {
EnumSet union = EnumSet.noneOf(Capability.class);
capSets.forEach(cs -> union.addAll(cs.caps));
return new CapabilitySet(union);
}
public static CapabilitySet unionOf(Collection caps) {
return CapabilitySet.ofSets(caps.stream().map(ToCapabilitySet::toCapabilitySet).toList());
}
public static CapabilitySet of(EnumSet caps) { return new CapabilitySet(EnumSet.copyOf(caps)); }
public static CapabilitySet of(Collection caps) { return new CapabilitySet(EnumSet.copyOf(caps)); }
public static CapabilitySet of(Capability... caps) { return new CapabilitySet(EnumSet.copyOf(List.of(caps))); }
public static CapabilitySet all() { return ALL_CAPABILITIES; }
public static CapabilitySet none() { return NO_CAPABILITIES; }
public boolean hasAll() { return this.caps.equals(ALL_CAPABILITIES.caps); }
public boolean hasNone() { return this.caps.equals(NO_CAPABILITIES.caps); }
public boolean has(CapabilitySet caps) { return this.caps.containsAll(caps.caps); }
public boolean has(Collection caps) { return this.caps.containsAll(caps); }
public boolean has(Capability... caps) { return this.caps.containsAll(List.of(caps)); }
public Set toCapabilityNames() {
return caps.stream().map(Capability::asString).collect(Collectors.toSet());
}
/** return name of the capability set if predefined, otherwise names of the individual capabilities */
public Set resolveNames() {
var predefinedName = toPredefinedName().orElse(null);
if (predefinedName != null) return Set.of(predefinedName);
return toCapabilityNames();
}
/** @return the name if this is a predefined capability set, or empty if not */
public Optional toPredefinedName() {
return PREDEFINED.entrySet().stream()
.filter(e -> e.getValue().equals(this))
.map(Map.Entry::getKey)
.findFirst();
}
public static Set resolveNames(Collection capabilities) {
var names = new HashSet();
for (ToCapabilitySet tcs : capabilities) {
if (tcs instanceof Capability c) names.add(c.asString());
else if (tcs instanceof CapabilitySet cs) names.addAll(cs.resolveNames());
else throw new IllegalArgumentException(tcs.toString());
}
return Set.copyOf(names);
}
public Set asSet() { return Collections.unmodifiableSet(caps); }
@Override
public String toString() {
return "CapabilitySet{" +
"caps=" + caps +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CapabilitySet that = (CapabilitySet) o;
return Objects.equals(caps, that.caps);
}
@Override
public int hashCode() {
return Objects.hash(caps);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy