All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.security.tls.CapabilitySet Maven / Gradle / Ivy

There is a newer version: 8.411.13
Show newest version
// 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 - 2024 Weber Informatics LLC | Privacy Policy