From b29b1459c69fdd1f6cfa875291ab6bb9ee7c60f9 Mon Sep 17 00:00:00 2001 From: Tomas Langer Date: Tue, 14 Jan 2020 01:10:41 +0100 Subject: [PATCH] Helidon Features. Signed-off-by: Tomas Langer --- .../io/helidon/common/HelidonFeatures.java | 127 +++++++++++++++--- .../java/io/helidon/common/HelidonFlavor.java | 2 +- .../helidon/common/HelidonFeaturesTest.java | 68 ++++++++++ .../java/io/helidon/config/BuilderImpl.java | 6 + .../config/encryption/EncryptionFilter.java | 7 +- .../helidon/config/etcd/EtcdConfigSource.java | 7 +- .../helidon/config/git/GitConfigSource.java | 7 +- .../hocon/internal/HoconConfigParser.java | 7 +- .../objectmapping/ObjectConfigMappers.java | 8 +- .../yaml/internal/YamlConfigParser.java | 7 +- .../grpc/client/GrpcServiceClient.java | 7 +- .../io/helidon/grpc/metrics/GrpcMetrics.java | 8 +- .../io/helidon/grpc/server/GrpcServer.java | 8 +- .../helidon/health/checks/HealthChecks.java | 9 +- .../java/io/helidon/health/HealthSupport.java | 8 +- .../media/jackson/server/JacksonSupport.java | 8 +- .../jsonb/server/JsonBindingSupport.java | 11 +- .../media/jsonp/server/JsonSupport.java | 8 +- .../io/helidon/metrics/MetricsSupport.java | 7 + .../metrics/prometheus/PrometheusSupport.java | 7 +- .../accesslog/AccessLogCdiExtension.java | 2 +- .../cdi/HelidonContainerImpl.java | 3 +- .../jwt/auth/cdi/JwtAuthCdiExtension.java | 8 +- .../microprofile/oidc/OidcCdiExtension.java | 6 + .../io/helidon/openapi/OpenAPISupport.java | 8 +- .../abac/policy/el/JavaxElPolicyExecutor.java | 8 +- .../security/abac/policy/PolicyValidator.java | 8 +- .../security/abac/role/RoleValidator.java | 7 +- .../security/abac/scope/ScopeValidator.java | 8 +- .../security/abac/time/TimeValidator.java | 8 +- .../integration/grpc/GrpcClientSecurity.java | 7 +- .../integration/grpc/GrpcSecurity.java | 7 +- .../jersey/client/ClientSecurityFilter.java | 7 +- .../jersey/SecurityFilterCommon.java | 7 +- .../integration/webserver/WebSecurity.java | 7 +- .../security/providers/abac/AbacProvider.java | 7 +- .../google/login/GoogleTokenProvider.java | 8 +- .../providers/header/HeaderAtnProvider.java | 11 +- .../httpauth/HttpBasicAuthProvider.java | 8 +- .../httpauth/HttpDigestAuthProvider.java | 8 +- .../providers/httpsign/HttpSignProvider.java | 8 +- .../idcs/mapper/IdcsMtRoleMapperProvider.java | 7 +- .../idcs/mapper/IdcsRoleMapperProvider.java | 7 +- .../security/providers/jwt/JwtProvider.java | 11 +- .../security/providers/oidc/OidcProvider.java | 11 +- .../java/io/helidon/security/Security.java | 6 + .../META-INF/microprofile-config.properties | 4 +- .../tracing/jaeger/JaegerTracerBuilder.java | 5 + .../jersey/client/ClientTracingFilter.java | 8 +- .../tracing/jersey/AbstractTracingFilter.java | 7 +- .../helidon/tracing/TracerProviderHelper.java | 8 +- .../tracing/zipkin/ZipkinTracerBuilder.java | 5 + .../webserver/accesslog/AccessLogSupport.java | 9 +- .../io/helidon/webserver/NettyWebServer.java | 2 +- .../helidon/webserver/ServerBasicConfig.java | 9 +- .../webserver/ServerConfiguration.java | 27 +++- .../java/io/helidon/webserver/WebServer.java | 7 +- 57 files changed, 542 insertions(+), 69 deletions(-) create mode 100644 common/common/src/test/java/io/helidon/common/HelidonFeaturesTest.java diff --git a/common/common/src/main/java/io/helidon/common/HelidonFeatures.java b/common/common/src/main/java/io/helidon/common/HelidonFeatures.java index 2aba7a9ee4c..eecb4f60249 100644 --- a/common/common/src/main/java/io/helidon/common/HelidonFeatures.java +++ b/common/common/src/main/java/io/helidon/common/HelidonFeatures.java @@ -17,9 +17,11 @@ package io.helidon.common; import java.util.EnumMap; -import java.util.HashSet; +import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; @@ -29,10 +31,10 @@ */ public final class HelidonFeatures { private static final Logger LOGGER = Logger.getLogger(HelidonFeatures.class.getName()); - - private static final Map> FEATURES = new EnumMap<>(HelidonFlavor.class); - private static final AtomicReference CURRENT_FLAVOR = new AtomicReference<>(); private static final AtomicBoolean PRINTED = new AtomicBoolean(); + private static final AtomicReference CURRENT_FLAVOR = new AtomicReference<>(); + private static final Map> FEATURES = new EnumMap<>(HelidonFlavor.class); + private static final Map> ROOT_FEATURE_NODES = new EnumMap<>(HelidonFlavor.class); private HelidonFeatures() { } @@ -43,12 +45,70 @@ private HelidonFeatures() { * class. In SE this would be one of the *Support classes or similar, * in MP most likely a CDI extension class. * + *

Example for security providers (SE) - application with Oidc provider: + *

    + *
  • Security calls {@code register(SE, "security")}
  • + *
  • OIDC provider calls {@code register(SE, "security", "authentication", "OIDC"}
  • + *
  • OIDC provider calls {@code register(SE, "security", "outbound", "OIDC"} if outbound is enabled
  • + *
+ * * @param flavor flavor to register a feature for - * @param name name of the feature + * @param path path of the feature (single value for root level features) */ - public static void register(HelidonFlavor flavor, String name) { - FEATURES.computeIfAbsent(flavor, key -> new HashSet<>()) - .add(name); + public static void register(HelidonFlavor flavor, String... path) { + if (path.length == 0) { + throw new IllegalArgumentException("At least the root feature name must be provided, but path was empty"); + } + if (path.length == 1) { + FEATURES.computeIfAbsent(flavor, key -> new TreeSet<>(String.CASE_INSENSITIVE_ORDER)) + .add(path[0]); + } + + var rootFeatures = ROOT_FEATURE_NODES.computeIfAbsent(flavor, it -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); + ensureNode(rootFeatures, path); + } + + /** + * Register a feature for all flavors. + * + *

Example for security providers (SE) - application with Oidc provider: + *

    + *
  • Security calls {@code register(SE, "security")}
  • + *
  • OIDC provider calls {@code register("security", "authentication", "OIDC"}
  • + *
  • OIDC provider calls {@code register("security", "outbound", "OIDC"} if outbound is enabled
  • + *
+ * + * @param path path of the feature (single value for root level features) + */ + public static void register(String... path) { + for (HelidonFlavor value : HelidonFlavor.values()) { + register(value, path); + } + } + + static Node ensureNode(Map rootFeatureNodes, String... path) { + // last part of the path is the name + if (path.length == 1) { + return rootFeatureNodes.computeIfAbsent(path[0], Node::new); + } + // we have a path, let's go through it + + // start with root + Node lastNode = ensureNode(rootFeatureNodes, path[0]); + for (int i = 1; i < path.length; i++) { + String pathElement = path[i]; + lastNode = ensureNode(pathElement, lastNode); + } + return lastNode; + } + + static Node ensureNode(String name, Node parent) { + return parent.children.computeIfAbsent(name, it -> new Node(name)); + } + + // testing only + static Map rootFeatureNodes(HelidonFlavor flavor) { + return ROOT_FEATURE_NODES.computeIfAbsent(flavor, it -> new HashMap<>()); } /** @@ -58,9 +118,11 @@ public static void register(HelidonFlavor flavor, String name) { * This is to make sure we do not print SE flavors in MP, and at the * same time can have this method used from Web Server. * This method only prints feature the first time it is called. + * * @param flavor flavor to print features for + * @param details set to {@code true} to print the tree structure of sub-features */ - public static void print(HelidonFlavor flavor) { + public static void print(HelidonFlavor flavor, boolean details) { CURRENT_FLAVOR.compareAndSet(null, HelidonFlavor.SE); HelidonFlavor currentFlavor = CURRENT_FLAVOR.get(); @@ -69,23 +131,56 @@ public static void print(HelidonFlavor flavor) { return; } - if (PRINTED.compareAndSet(false, true)) { - Set strings = FEATURES.get(currentFlavor); - if (null == strings) { - LOGGER.info("Helidon " + currentFlavor + " " + Version.VERSION + " has no registered features"); - } else { - LOGGER.info("Helidon " + currentFlavor + " " + Version.VERSION + " features: " + strings); - } + if (!PRINTED.compareAndSet(false, true)) { + return; + } + Set strings = FEATURES.get(currentFlavor); + if (null == strings) { + LOGGER.info("Helidon " + currentFlavor + " " + Version.VERSION + " has no registered features"); + } else { + LOGGER.info("Helidon " + currentFlavor + " " + Version.VERSION + " features: " + strings); + } + if (details) { + LOGGER.info("Detailed feature tree:"); + FEATURES.get(currentFlavor) + .forEach(name -> printDetails(name, ROOT_FEATURE_NODES.get(currentFlavor).get(name), 0)); } } + private static void printDetails(String name, Node node, int level) { + + System.out.println(" ".repeat(level) + name); + + node.children.forEach((childName, childNode) -> printDetails(childName, childNode, level + 1)); + } + /** * Set the current Helidon flavor. Features will only be printed for the * flavor configured. * + * The first flavor configured wins. + * * @param flavor current flavor */ public static void flavor(HelidonFlavor flavor) { CURRENT_FLAVOR.compareAndSet(null, flavor); } + + static final class Node { + private final Map children = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private final String name; + + Node(String name) { + this.name = name; + } + + String name() { + return name; + } + + // for tests + Map children() { + return children; + } + } } diff --git a/common/common/src/main/java/io/helidon/common/HelidonFlavor.java b/common/common/src/main/java/io/helidon/common/HelidonFlavor.java index 798cd56c8a0..397bdc84e91 100644 --- a/common/common/src/main/java/io/helidon/common/HelidonFlavor.java +++ b/common/common/src/main/java/io/helidon/common/HelidonFlavor.java @@ -21,7 +21,7 @@ */ public enum HelidonFlavor { /** - * The "standard edition" flavor. + * The "Standard Edition" flavor. */ SE, /** diff --git a/common/common/src/test/java/io/helidon/common/HelidonFeaturesTest.java b/common/common/src/test/java/io/helidon/common/HelidonFeaturesTest.java new file mode 100644 index 00000000000..4e9847c4f5b --- /dev/null +++ b/common/common/src/test/java/io/helidon/common/HelidonFeaturesTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.common; + +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import static io.helidon.common.HelidonFeatures.register; +import static io.helidon.common.HelidonFlavor.SE; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; + +/** + * Unit test for {@link HelidonFeatures}. + */ +class HelidonFeaturesTest { + @Test + void testFeatureTree() { + register(SE, "security"); + register(SE, "security", "authorization", "ABAC"); + register(SE, "security", "authentication", "OIDC"); + register(SE, "security", "outbound", "OIDC"); + register(SE, "tracing"); + register(SE, "tracing", "zipkin"); + register(SE, "complex"); + register(SE, "complex", "first"); + register(SE, "complex", "first", "second"); + register(SE, "complex", "first", "second", "third"); + register(SE, "complex", "first", "second", "third2"); + + Map features = HelidonFeatures.rootFeatureNodes(SE); + + assertThat(features.keySet(), containsInAnyOrder("security", "tracing", "complex")); + + HelidonFeatures.Node security = features.get("security"); + assertThat(security.name(), is("security")); + + Map children = security.children(); + assertThat(children.keySet(), containsInAnyOrder("authorization", "authentication", "outbound")); + HelidonFeatures.Node node = children.get("authentication"); + assertThat(node.name(), is("authentication")); + HelidonFeatures.Node oidc = node.children().get("OIDC"); + assertThat(oidc.name(), is("OIDC")); + assertThat(oidc.children(), is(Map.of())); + + HelidonFeatures.Node second = features.get("complex").children().get("first").children().get("second"); + Map secondChildren = second.children(); + assertThat(secondChildren.keySet(), containsInAnyOrder("third", "third2")); + + HelidonFeatures.print(SE, true); + } +} \ No newline at end of file diff --git a/config/config/src/main/java/io/helidon/config/BuilderImpl.java b/config/config/src/main/java/io/helidon/config/BuilderImpl.java index 613cc7fdf49..b79900328bc 100644 --- a/config/config/src/main/java/io/helidon/config/BuilderImpl.java +++ b/config/config/src/main/java/io/helidon/config/BuilderImpl.java @@ -39,6 +39,8 @@ import javax.annotation.Priority; import io.helidon.common.GenericType; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.Prioritized; import io.helidon.common.serviceloader.HelidonServiceLoader; import io.helidon.common.serviceloader.Priorities; @@ -65,6 +67,10 @@ class BuilderImpl implements Config.Builder { static final Executor DEFAULT_CHANGES_EXECUTOR = Executors.newCachedThreadPool(new ConfigThreadFactory("config")); + static { + HelidonFeatures.register(HelidonFlavor.SE, "Config"); + } + /* * Config sources */ diff --git a/config/encryption/src/main/java/io/helidon/config/encryption/EncryptionFilter.java b/config/encryption/src/main/java/io/helidon/config/encryption/EncryptionFilter.java index 2f43ca540ff..a8d5a67400a 100644 --- a/config/encryption/src/main/java/io/helidon/config/encryption/EncryptionFilter.java +++ b/config/encryption/src/main/java/io/helidon/config/encryption/EncryptionFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.common.pki.KeyConfig; import io.helidon.config.Config; import io.helidon.config.MissingValueException; @@ -66,6 +67,10 @@ public final class EncryptionFilter implements ConfigFilter { private static final String PREFIX_ALIAS = "${ALIAS="; private static final String PREFIX_CLEAR = "${CLEAR="; + static { + HelidonFeatures.register("Config", "Encryption"); + } + private final PrivateKey privateKey; private final char[] masterPassword; diff --git a/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java b/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java index d53fab43e90..400dd9619ea 100644 --- a/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java +++ b/config/etcd/src/main/java/io/helidon/config/etcd/EtcdConfigSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.config.ConfigException; import io.helidon.config.ConfigHelper; @@ -43,6 +44,10 @@ public class EtcdConfigSource extends AbstractParsableConfigSource { private static final Logger LOGGER = Logger.getLogger(EtcdConfigSource.class.getName()); + static { + HelidonFeatures.register("Config", "etcd"); + } + private final EtcdEndpoint endpoint; private final EtcdClient client; diff --git a/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java b/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java index ffcb1b52bd9..cadc0bbb370 100644 --- a/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java +++ b/config/git/src/main/java/io/helidon/config/git/GitConfigSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.config.ConfigException; import io.helidon.config.ConfigHelper; @@ -61,6 +62,10 @@ public class GitConfigSource extends AbstractParsableConfigSource { private static final Logger LOGGER = Logger.getLogger(GitConfigSource.class.getName()); + static { + HelidonFeatures.register("Config", "git"); + } + private final URI uri; private final String branch; diff --git a/config/hocon/src/main/java/io/helidon/config/hocon/internal/HoconConfigParser.java b/config/hocon/src/main/java/io/helidon/config/hocon/internal/HoconConfigParser.java index e40232b64ef..132d267d3ae 100644 --- a/config/hocon/src/main/java/io/helidon/config/hocon/internal/HoconConfigParser.java +++ b/config/hocon/src/main/java/io/helidon/config/hocon/internal/HoconConfigParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import javax.annotation.Priority; +import io.helidon.common.HelidonFeatures; import io.helidon.config.ConfigException; import io.helidon.config.ConfigHelper; import io.helidon.config.spi.ConfigNode.ListNode; @@ -71,6 +72,10 @@ public class HoconConfigParser implements ConfigParser { private static final Set SUPPORTED_MEDIA_TYPES = Set.of(MEDIA_TYPE_APPLICATION_HOCON, MEDIA_TYPE_APPLICATION_JSON); + static { + HelidonFeatures.register("Config", "HOCON"); + } + private final boolean resolvingEnabled; private final ConfigResolveOptions resolveOptions; diff --git a/config/object-mapping/src/main/java/io/helidon/config/objectmapping/ObjectConfigMappers.java b/config/object-mapping/src/main/java/io/helidon/config/objectmapping/ObjectConfigMappers.java index 7e99713b2e3..2559c936cd1 100644 --- a/config/object-mapping/src/main/java/io/helidon/config/objectmapping/ObjectConfigMappers.java +++ b/config/object-mapping/src/main/java/io/helidon/config/objectmapping/ObjectConfigMappers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import java.util.Collection; import java.util.function.Function; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.config.ConfigMappingException; import io.helidon.config.MissingValueException; @@ -29,6 +30,11 @@ * Various mappers used in {@link ObjectConfigMapperProvider}. */ class ObjectConfigMappers { + + static { + HelidonFeatures.register("Config", "Object Mapping"); + } + abstract static class MethodHandleConfigMapper implements Function { private final Class type; private final String methodName; diff --git a/config/yaml/src/main/java/io/helidon/config/yaml/internal/YamlConfigParser.java b/config/yaml/src/main/java/io/helidon/config/yaml/internal/YamlConfigParser.java index fa2d1842ab5..2292bc39804 100644 --- a/config/yaml/src/main/java/io/helidon/config/yaml/internal/YamlConfigParser.java +++ b/config/yaml/src/main/java/io/helidon/config/yaml/internal/YamlConfigParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import javax.annotation.Priority; +import io.helidon.common.HelidonFeatures; import io.helidon.config.ConfigException; import io.helidon.config.ConfigHelper; import io.helidon.config.spi.ConfigNode.ListNode; @@ -59,6 +60,10 @@ public class YamlConfigParser implements ConfigParser { private static final Set SUPPORTED_MEDIA_TYPES = Set.of(MEDIA_TYPE_APPLICATION_YAML); + static { + HelidonFeatures.register("Config", "YAML"); + } + /** * Default constructor needed by Java Service loader. */ diff --git a/grpc/client/src/main/java/io/helidon/grpc/client/GrpcServiceClient.java b/grpc/client/src/main/java/io/helidon/grpc/client/GrpcServiceClient.java index 3c6bb22ab37..c98a20016c4 100644 --- a/grpc/client/src/main/java/io/helidon/grpc/client/GrpcServiceClient.java +++ b/grpc/client/src/main/java/io/helidon/grpc/client/GrpcServiceClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,8 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.grpc.core.InterceptorPriorities; import io.helidon.grpc.core.MethodHandler; import io.helidon.grpc.core.PriorityBag; @@ -45,6 +47,9 @@ * A gRPC Client for a specific gRPC service. */ public class GrpcServiceClient { + static { + HelidonFeatures.register(HelidonFlavor.SE, "gRPC Client"); + } private final HashMap methodStubs; diff --git a/grpc/metrics/src/main/java/io/helidon/grpc/metrics/GrpcMetrics.java b/grpc/metrics/src/main/java/io/helidon/grpc/metrics/GrpcMetrics.java index 86e8aec2900..9066f7328d9 100644 --- a/grpc/metrics/src/main/java/io/helidon/grpc/metrics/GrpcMetrics.java +++ b/grpc/metrics/src/main/java/io/helidon/grpc/metrics/GrpcMetrics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import javax.annotation.Priority; +import io.helidon.common.HelidonFeatures; import io.helidon.common.metrics.InternalBridge; import io.helidon.common.metrics.InternalBridge.Metadata.MetadataBuilder; import io.helidon.grpc.core.GrpcHelper; @@ -52,6 +53,11 @@ public class GrpcMetrics implements ServerInterceptor, ServiceDescriptor.Configurer, MethodDescriptor.Configurer { + static { + HelidonFeatures.register("gRPC Server", "Metrics"); + HelidonFeatures.register("gRPC Client", "Metrics"); + } + /** * The registry of vendor metrics. */ diff --git a/grpc/server/src/main/java/io/helidon/grpc/server/GrpcServer.java b/grpc/server/src/main/java/io/helidon/grpc/server/GrpcServer.java index bffa14dd693..1be0fbd7c45 100644 --- a/grpc/server/src/main/java/io/helidon/grpc/server/GrpcServer.java +++ b/grpc/server/src/main/java/io/helidon/grpc/server/GrpcServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ import java.util.concurrent.CompletionStage; import java.util.function.Supplier; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.context.Context; import io.helidon.grpc.core.PriorityBag; @@ -243,6 +245,10 @@ static Builder builder(GrpcRouting routing) { final class Builder implements io.helidon.common.Builder { + static { + HelidonFeatures.register(HelidonFlavor.SE, "gRPC Server"); + } + private final GrpcRouting routing; private GrpcServerConfiguration configuration; diff --git a/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java b/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java index 1b3bf0a401f..75d9a4ac74b 100644 --- a/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java +++ b/health/health-checks/src/main/java/io/helidon/health/checks/HealthChecks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ import java.lang.management.ManagementFactory; +import io.helidon.common.HelidonFeatures; + import org.eclipse.microprofile.health.HealthCheck; /** @@ -26,6 +28,11 @@ */ public final class HealthChecks { private static final boolean IS_GRAAL_VM = Boolean.getBoolean("com.oracle.graalvm.isaot"); + + static { + HelidonFeatures.register("Health", "Built-ins"); + } + private HealthChecks() { } diff --git a/health/health/src/main/java/io/helidon/health/HealthSupport.java b/health/health/src/main/java/io/helidon/health/HealthSupport.java index 7bae64e68f2..5f91648fc5a 100644 --- a/health/health/src/main/java/io/helidon/health/HealthSupport.java +++ b/health/health/src/main/java/io/helidon/health/HealthSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,8 @@ import javax.json.JsonObject; import javax.json.JsonObjectBuilder; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.Http; import io.helidon.config.Config; import io.helidon.media.jsonp.server.JsonSupport; @@ -61,6 +63,10 @@ public final class HealthSupport implements Service { private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); + static { + HelidonFeatures.register(HelidonFlavor.SE, "Health"); + } + private final boolean enabled; private final String webContext; private final List allChecks = new LinkedList<>(); diff --git a/media/jackson/server/src/main/java/io/helidon/media/jackson/server/JacksonSupport.java b/media/jackson/server/src/main/java/io/helidon/media/jackson/server/JacksonSupport.java index 56ec20a6c6e..b6f3b3c0f37 100644 --- a/media/jackson/server/src/main/java/io/helidon/media/jackson/server/JacksonSupport.java +++ b/media/jackson/server/src/main/java/io/helidon/media/jackson/server/JacksonSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ import java.util.Objects; import java.util.function.BiFunction; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.media.jackson.common.JacksonProcessing; import io.helidon.webserver.Handler; import io.helidon.webserver.JsonService; @@ -37,6 +39,10 @@ * support to Helidon. */ public final class JacksonSupport extends JsonService { + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer", "Jackson"); + } + private final BiFunction objectMapperProvider; /** diff --git a/media/jsonb/server/src/main/java/io/helidon/media/jsonb/server/JsonBindingSupport.java b/media/jsonb/server/src/main/java/io/helidon/media/jsonb/server/JsonBindingSupport.java index 370c395ba4f..e9b0f006c6d 100644 --- a/media/jsonb/server/src/main/java/io/helidon/media/jsonb/server/JsonBindingSupport.java +++ b/media/jsonb/server/src/main/java/io/helidon/media/jsonb/server/JsonBindingSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.media.jsonb.common.JsonBinding; import io.helidon.webserver.Handler; import io.helidon.webserver.JsonService; @@ -36,12 +38,15 @@ * href="http://json-b.net/">JSON-B support to Helidon. */ public final class JsonBindingSupport extends JsonService { + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer", "JSON-B"); + } private final BiFunction jsonbProvider; private JsonBindingSupport(final BiFunction jsonbProvider) { + ? super ServerResponse, + ? extends Jsonb> jsonbProvider) { super(); this.jsonbProvider = Objects.requireNonNull(jsonbProvider); } diff --git a/media/jsonp/server/src/main/java/io/helidon/media/jsonp/server/JsonSupport.java b/media/jsonp/server/src/main/java/io/helidon/media/jsonp/server/JsonSupport.java index a24575e2afd..5e550478a66 100644 --- a/media/jsonp/server/src/main/java/io/helidon/media/jsonp/server/JsonSupport.java +++ b/media/jsonp/server/src/main/java/io/helidon/media/jsonp/server/JsonSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,8 @@ import javax.json.JsonStructure; import javax.json.JsonWriter; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.Content; import io.helidon.common.http.DataChunk; import io.helidon.common.http.Reader; @@ -76,6 +78,10 @@ public final class JsonSupport extends JsonService { private static final JsonSupport INSTANCE = new JsonSupport(JsonProcessing.create()); + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer", "JSON-P"); + } + private final JsonProcessing processingSupport; private JsonSupport(JsonProcessing processing) { diff --git a/metrics/metrics/src/main/java/io/helidon/metrics/MetricsSupport.java b/metrics/metrics/src/main/java/io/helidon/metrics/MetricsSupport.java index 386ecbdc45d..4dd5f4adcbc 100644 --- a/metrics/metrics/src/main/java/io/helidon/metrics/MetricsSupport.java +++ b/metrics/metrics/src/main/java/io/helidon/metrics/MetricsSupport.java @@ -41,6 +41,8 @@ import javax.json.JsonObjectBuilder; import javax.json.JsonValue; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.Http; import io.helidon.common.http.MediaType; import io.helidon.config.Config; @@ -94,6 +96,11 @@ public final class MetricsSupport implements Service { private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); private static final String DEFAULT_CONTEXT = "/metrics"; + + static { + HelidonFeatures.register(HelidonFlavor.SE, "Metrics"); + } + private final String context; private final RegistryFactory rf; diff --git a/metrics/prometheus/src/main/java/io/helidon/metrics/prometheus/PrometheusSupport.java b/metrics/prometheus/src/main/java/io/helidon/metrics/prometheus/PrometheusSupport.java index 8c76f28c592..739dd07e3c0 100644 --- a/metrics/prometheus/src/main/java/io/helidon/metrics/prometheus/PrometheusSupport.java +++ b/metrics/prometheus/src/main/java/io/helidon/metrics/prometheus/PrometheusSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import java.util.HashSet; import java.util.Set; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.MediaType; import io.helidon.webserver.Routing; import io.helidon.webserver.ServerRequest; @@ -42,6 +44,9 @@ * It is possible to use */ public final class PrometheusSupport implements Service { + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer", "Prometheus"); + } /** * Standard path of Prometheus client resource: {@code /metrics}. diff --git a/microprofile/access-log/src/main/java/io/helidon/microprofile/accesslog/AccessLogCdiExtension.java b/microprofile/access-log/src/main/java/io/helidon/microprofile/accesslog/AccessLogCdiExtension.java index c1a9ae370b2..90f8e8f1d4a 100644 --- a/microprofile/access-log/src/main/java/io/helidon/microprofile/accesslog/AccessLogCdiExtension.java +++ b/microprofile/access-log/src/main/java/io/helidon/microprofile/accesslog/AccessLogCdiExtension.java @@ -34,7 +34,7 @@ */ public class AccessLogCdiExtension implements Extension { static { - HelidonFeatures.register(HelidonFlavor.MP, "AccessLog"); + HelidonFeatures.register(HelidonFlavor.MP, "Server", "AccessLog"); } private void setUpAccessLog(@Observes @Priority(PLATFORM_BEFORE + 10) @RuntimeStart Config config, diff --git a/microprofile/cdi/src/main/java/io/helidon/microprofile/cdi/HelidonContainerImpl.java b/microprofile/cdi/src/main/java/io/helidon/microprofile/cdi/HelidonContainerImpl.java index c168b33e118..d0f0ac56370 100644 --- a/microprofile/cdi/src/main/java/io/helidon/microprofile/cdi/HelidonContainerImpl.java +++ b/microprofile/cdi/src/main/java/io/helidon/microprofile/cdi/HelidonContainerImpl.java @@ -299,7 +299,8 @@ public void close() throws SecurityException { now = System.currentTimeMillis() - now; LOGGER.fine("Container started in " + now + " millis (this excludes the initialization time)"); - HelidonFeatures.print(HelidonFlavor.MP); + HelidonFeatures.print(HelidonFlavor.MP, config.get("features.print-details").asBoolean().orElse(false)); + return this; } diff --git a/microprofile/jwt-auth/jwt-auth-cdi/src/main/java/io/helidon/microprofile/jwt/auth/cdi/JwtAuthCdiExtension.java b/microprofile/jwt-auth/jwt-auth-cdi/src/main/java/io/helidon/microprofile/jwt/auth/cdi/JwtAuthCdiExtension.java index ea87aed0cf0..db580cdec6e 100644 --- a/microprofile/jwt-auth/jwt-auth-cdi/src/main/java/io/helidon/microprofile/jwt/auth/cdi/JwtAuthCdiExtension.java +++ b/microprofile/jwt-auth/jwt-auth-cdi/src/main/java/io/helidon/microprofile/jwt/auth/cdi/JwtAuthCdiExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,9 @@ import javax.json.JsonString; import javax.json.JsonValue; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; + import org.eclipse.microprofile.jwt.Claim; import org.eclipse.microprofile.jwt.ClaimValue; import org.eclipse.microprofile.jwt.Claims; @@ -67,6 +70,9 @@ * JWT Authentication CDI extension class. */ public class JwtAuthCdiExtension implements Extension { + static { + HelidonFeatures.register(HelidonFlavor.MP, "Security", "MP", "JWT-Auth"); + } private final List qualifiers = new LinkedList<>(); diff --git a/microprofile/oidc/src/main/java/io/helidon/microprofile/oidc/OidcCdiExtension.java b/microprofile/oidc/src/main/java/io/helidon/microprofile/oidc/OidcCdiExtension.java index 5d2582f608e..d8abd80ecae 100644 --- a/microprofile/oidc/src/main/java/io/helidon/microprofile/oidc/OidcCdiExtension.java +++ b/microprofile/oidc/src/main/java/io/helidon/microprofile/oidc/OidcCdiExtension.java @@ -22,6 +22,8 @@ import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.config.Config; import io.helidon.microprofile.cdi.RuntimeStart; import io.helidon.microprofile.server.ServerCdiExtension; @@ -31,6 +33,10 @@ * Microprofile extension that brings support for Open ID Connect. */ public final class OidcCdiExtension implements Extension { + static { + HelidonFeatures.register(HelidonFlavor.MP, "Security", "MP", "OIDC"); + } + private Config config; private void configure(@Observes @RuntimeStart Config config) { diff --git a/openapi/src/main/java/io/helidon/openapi/OpenAPISupport.java b/openapi/src/main/java/io/helidon/openapi/OpenAPISupport.java index 99880c059f9..c0885bab723 100644 --- a/openapi/src/main/java/io/helidon/openapi/OpenAPISupport.java +++ b/openapi/src/main/java/io/helidon/openapi/OpenAPISupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,8 @@ import java.util.logging.Logger; import java.util.stream.Collectors; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.Http; import io.helidon.common.http.MediaType; import io.helidon.config.Config; @@ -83,6 +85,10 @@ public class OpenAPISupport implements Service { private static final String OPENAPI_EXPLICIT_STATIC_FILE_LOG_MESSAGE_FORMAT = "Using specified OpenAPI static file %s"; private static final String OPENAPI_DEFAULTED_STATIC_FILE_LOG_MESSAGE_FORMAT = "Using default OpenAPI static file %s"; + static { + HelidonFeatures.register(HelidonFlavor.SE, "OpenAPI"); + } + private final String webContext; private final OpenAPI model; diff --git a/security/abac/policy-el/src/main/java/io/helidon/security/abac/policy/el/JavaxElPolicyExecutor.java b/security/abac/policy-el/src/main/java/io/helidon/security/abac/policy/el/JavaxElPolicyExecutor.java index e9587f62cf7..61aab1e64b4 100644 --- a/security/abac/policy-el/src/main/java/io/helidon/security/abac/policy/el/JavaxElPolicyExecutor.java +++ b/security/abac/policy-el/src/main/java/io/helidon/security/abac/policy/el/JavaxElPolicyExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import javax.el.VariableMapper; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.ProviderRequest; import io.helidon.security.SecurityContext; @@ -46,6 +47,11 @@ public final class JavaxElPolicyExecutor implements PolicyExecutor { private static final Logger LOGGER = Logger.getLogger(JavaxElPolicyExecutor.class.getName()); private static final AttributeResolver ATTRIBUTE_RESOLVER = new AttributeResolver(); + + static { + HelidonFeatures.register("Security", "Authorization", "ABAC", "Policy", "EL"); + } + private final ExpressionFactory ef; private final List customMethods = new LinkedList<>(); diff --git a/security/abac/policy/src/main/java/io/helidon/security/abac/policy/PolicyValidator.java b/security/abac/policy/src/main/java/io/helidon/security/abac/policy/PolicyValidator.java index ef90e93de7a..ce1dd4b2bb7 100644 --- a/security/abac/policy/src/main/java/io/helidon/security/abac/policy/PolicyValidator.java +++ b/security/abac/policy/src/main/java/io/helidon/security/abac/policy/PolicyValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ import java.util.logging.Logger; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.EndpointConfig; import io.helidon.security.ProviderRequest; @@ -59,6 +60,11 @@ */ public final class PolicyValidator implements AbacValidator { private static final Logger LOGGER = Logger.getLogger(PolicyValidator.class.getName()); + + static { + HelidonFeatures.register("Security", "Authorization", "ABAC", "Policy"); + } + private final List executors = new LinkedList<>(); private PolicyValidator(Builder builder) { diff --git a/security/abac/role/src/main/java/io/helidon/security/abac/role/RoleValidator.java b/security/abac/role/src/main/java/io/helidon/security/abac/role/RoleValidator.java index 18cc2fe0d7e..7b75ed87239 100644 --- a/security/abac/role/src/main/java/io/helidon/security/abac/role/RoleValidator.java +++ b/security/abac/role/src/main/java/io/helidon/security/abac/role/RoleValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ import javax.annotation.security.RolesAllowed; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.EndpointConfig; import io.helidon.security.ProviderRequest; @@ -60,6 +61,10 @@ * This validator supports both {@link RolesAllowed} and {@link Roles} annotations. */ public final class RoleValidator implements AbacValidator { + static { + HelidonFeatures.register("Security", "Authorization", "ABAC", "Role"); + } + private RoleValidator() { } diff --git a/security/abac/scope/src/main/java/io/helidon/security/abac/scope/ScopeValidator.java b/security/abac/scope/src/main/java/io/helidon/security/abac/scope/ScopeValidator.java index f9db90c5fd2..22488469a42 100644 --- a/security/abac/scope/src/main/java/io/helidon/security/abac/scope/ScopeValidator.java +++ b/security/abac/scope/src/main/java/io/helidon/security/abac/scope/ScopeValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import java.util.Set; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.EndpointConfig; import io.helidon.security.Grant; @@ -50,6 +51,11 @@ public final class ScopeValidator implements AbacValidator { private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); + + static { + HelidonFeatures.register("Security", "Authorization", "ABAC", "Time"); + } + private TimeValidator() { } diff --git a/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcClientSecurity.java b/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcClientSecurity.java index af5af55e0d1..56c629bb91d 100644 --- a/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcClientSecurity.java +++ b/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcClientSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.util.Map; import java.util.concurrent.Executor; +import io.helidon.common.HelidonFeatures; import io.helidon.security.EndpointConfig; import io.helidon.security.OutboundSecurityClientBuilder; import io.helidon.security.OutboundSecurityResponse; @@ -52,6 +53,10 @@ public final class GrpcClientSecurity */ public static final String PROPERTY_PROVIDER = "io.helidon.security.integration.grpc.GrpcClientSecurity.explicitProvider"; + static { + HelidonFeatures.register("Security", "Integration", "gRPC Client"); + } + private final SecurityContext context; private final Map properties; diff --git a/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcSecurity.java b/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcSecurity.java index b19e362ff08..2bb5024c27d 100644 --- a/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcSecurity.java +++ b/security/integration/grpc/src/main/java/io/helidon/security/integration/grpc/GrpcSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import javax.annotation.Priority; +import io.helidon.common.HelidonFeatures; import io.helidon.common.context.Contexts; import io.helidon.config.Config; import io.helidon.grpc.core.InterceptorPriorities; @@ -152,6 +153,10 @@ public final class GrpcSecurity private static final AtomicInteger SECURITY_COUNTER = new AtomicInteger(); + static { + HelidonFeatures.register("Security", "Integration", "gRPC Server"); + } + private final Security security; private final Optional config; private final GrpcSecurityHandler defaultHandler; diff --git a/security/integration/jersey-client/src/main/java/io/helidon/security/integration/jersey/client/ClientSecurityFilter.java b/security/integration/jersey-client/src/main/java/io/helidon/security/integration/jersey/client/ClientSecurityFilter.java index 1c2c3da1e32..5f12a85a1e0 100644 --- a/security/integration/jersey-client/src/main/java/io/helidon/security/integration/jersey/client/ClientSecurityFilter.java +++ b/security/integration/jersey-client/src/main/java/io/helidon/security/integration/jersey/client/ClientSecurityFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.Provider; +import io.helidon.common.HelidonFeatures; import io.helidon.common.context.Contexts; import io.helidon.security.EndpointConfig; import io.helidon.security.OutboundSecurityClientBuilder; @@ -54,6 +55,10 @@ public class ClientSecurityFilter implements ClientRequestFilter { private static final Logger LOGGER = Logger.getLogger(ClientSecurityFilter.class.getName()); + static { + HelidonFeatures.register("Security", "Integration", "Jersey Client"); + } + /** * Create an instance of this filter (used by Jersey or for unit tests, do not use explicitly in your production code). */ diff --git a/security/integration/jersey/src/main/java/io/helidon/security/integration/jersey/SecurityFilterCommon.java b/security/integration/jersey/src/main/java/io/helidon/security/integration/jersey/SecurityFilterCommon.java index cd05733b170..91447d69101 100644 --- a/security/integration/jersey/src/main/java/io/helidon/security/integration/jersey/SecurityFilterCommon.java +++ b/security/integration/jersey/src/main/java/io/helidon/security/integration/jersey/SecurityFilterCommon.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.AuthorizationResponse; @@ -52,6 +53,10 @@ abstract class SecurityFilterCommon { static final String PROP_FILTER_CONTEXT = "io.helidon.security.jersey.FilterContext"; + static { + HelidonFeatures.register("Security", "Integration", "Jersey"); + } + @Context private Security security; diff --git a/security/integration/webserver/src/main/java/io/helidon/security/integration/webserver/WebSecurity.java b/security/integration/webserver/src/main/java/io/helidon/security/integration/webserver/WebSecurity.java index 4f1a2c914f0..f04912e2f76 100644 --- a/security/integration/webserver/src/main/java/io/helidon/security/integration/webserver/WebSecurity.java +++ b/security/integration/webserver/src/main/java/io/helidon/security/integration/webserver/WebSecurity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import io.helidon.common.HelidonFeatures; import io.helidon.common.http.Http; import io.helidon.config.Config; import io.helidon.config.ConfigValue; @@ -94,6 +95,10 @@ public final class WebSecurity implements Service { private static final AtomicInteger SECURITY_COUNTER = new AtomicInteger(); + static { + HelidonFeatures.register("Security", "Integration", "WebServer"); + } + private final Security security; private final Config config; private final SecurityHandler defaultHandler; diff --git a/security/providers/abac/src/main/java/io/helidon/security/providers/abac/AbacProvider.java b/security/providers/abac/src/main/java/io/helidon/security/providers/abac/AbacProvider.java index fb0ee92f789..cbb1115e59d 100644 --- a/security/providers/abac/src/main/java/io/helidon/security/providers/abac/AbacProvider.java +++ b/security/providers/abac/src/main/java/io/helidon/security/providers/abac/AbacProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import javax.annotation.security.RolesAllowed; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthorizationResponse; import io.helidon.security.EndpointConfig; @@ -54,6 +55,10 @@ * @see #create(Config) */ public final class AbacProvider extends SynchronousProvider implements AuthorizationProvider { + static { + HelidonFeatures.register("Security", "Authorization", "ABAC"); + } + private final List> validators = new ArrayList<>(); private final Set> supportedAnnotations; private final Set supportedConfigKeys; diff --git a/security/providers/google-login/src/main/java/io/helidon/security/providers/google/login/GoogleTokenProvider.java b/security/providers/google-login/src/main/java/io/helidon/security/providers/google/login/GoogleTokenProvider.java index d922c17cf28..b5fec06daa1 100644 --- a/security/providers/google-login/src/main/java/io/helidon/security/providers/google/login/GoogleTokenProvider.java +++ b/security/providers/google-login/src/main/java/io/helidon/security/providers/google/login/GoogleTokenProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.EndpointConfig; @@ -76,6 +77,11 @@ public final class GoogleTokenProvider extends SynchronousProvider implements Au static final long TIME_SKEW_SECONDS = TimeUnit.SECONDS.convert(5, TimeUnit.MINUTES); + static { + HelidonFeatures.register("Security", "Authentication", "Google-Login"); + HelidonFeatures.register("Security", "Outbound", "Google-Login"); + } + private final EvictableCache subjectCache = EvictableCache.builder() .evictor((key, record) -> record.getValidSupplier().get()) .build(); diff --git a/security/providers/header/src/main/java/io/helidon/security/providers/header/HeaderAtnProvider.java b/security/providers/header/src/main/java/io/helidon/security/providers/header/HeaderAtnProvider.java index 0e4072c0c4b..6ec0d361e6d 100644 --- a/security/providers/header/src/main/java/io/helidon/security/providers/header/HeaderAtnProvider.java +++ b/security/providers/header/src/main/java/io/helidon/security/providers/header/HeaderAtnProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Optional; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.EndpointConfig; @@ -40,6 +41,10 @@ * This provider also supports propagation of identity through a header. */ public class HeaderAtnProvider extends SynchronousProvider implements AuthenticationProvider, OutboundSecurityProvider { + static { + HelidonFeatures.register("Security", "Authentication", "Header"); + } + private final boolean optional; private final boolean authenticate; private final boolean propagate; @@ -54,6 +59,10 @@ private HeaderAtnProvider(Builder builder) { this.subjectType = builder.subjectType; this.atnTokenHandler = builder.atnTokenHandler; this.outboundTokenHandler = builder.outboundTokenHandler; + + if (propagate) { + HelidonFeatures.register("Security", "Outbound", "Header"); + } } /** diff --git a/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpBasicAuthProvider.java b/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpBasicAuthProvider.java index b9a580e860a..2952cfda309 100644 --- a/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpBasicAuthProvider.java +++ b/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpBasicAuthProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import io.helidon.common.HelidonFeatures; import io.helidon.common.serviceloader.HelidonServiceLoader; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; @@ -67,6 +68,11 @@ public class HttpBasicAuthProvider extends SynchronousProvider implements Authen private static final Pattern CREDENTIAL_PATTERN = Pattern.compile("(.*):(.*)"); private static final char[] EMPTY_PASSWORD = new char[0]; + static { + HelidonFeatures.register("Security", "Authentication", "Basic-Auth"); + HelidonFeatures.register("Security", "Outbound", "Basic-Auth"); + } + private final List userStores; private final String realm; private final SubjectType subjectType; diff --git a/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpDigestAuthProvider.java b/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpDigestAuthProvider.java index 9e75a5285f9..ffae3c7bfb9 100644 --- a/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpDigestAuthProvider.java +++ b/security/providers/http-auth/src/main/java/io/helidon/security/providers/httpauth/HttpDigestAuthProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import javax.crypto.Cipher; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.Principal; @@ -56,6 +57,11 @@ public final class HttpDigestAuthProvider extends SynchronousProvider implements private static final int SALT_LENGTH = 16; private static final int AES_NONCE_LENGTH = 12; private static final Logger LOGGER = Logger.getLogger(HttpDigestAuthProvider.class.getName()); + + static { + HelidonFeatures.register("Security", "Authentication", "Digest-Auth"); + } + private final List digestQopOptions = new LinkedList<>(); private final SecureUserStore userStore; private final String realm; diff --git a/security/providers/http-sign/src/main/java/io/helidon/security/providers/httpsign/HttpSignProvider.java b/security/providers/http-sign/src/main/java/io/helidon/security/providers/httpsign/HttpSignProvider.java index 91717fad888..488943b9c11 100644 --- a/security/providers/http-sign/src/main/java/io/helidon/security/providers/httpsign/HttpSignProvider.java +++ b/security/providers/http-sign/src/main/java/io/helidon/security/providers/httpsign/HttpSignProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.EndpointConfig; @@ -69,6 +70,11 @@ public final class HttpSignProvider implements AuthenticationProvider, OutboundS .build(); static final String ATTRIB_NAME_KEY_ID = HttpSignProvider.class.getName() + ".keyId"; + static { + HelidonFeatures.register("Security", "Authentication", "Http-Sign"); + HelidonFeatures.register("Security", "Outbound", "Http-Sign"); + } + private final boolean optional; private final String realm; private final Set acceptHeaders; diff --git a/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsMtRoleMapperProvider.java b/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsMtRoleMapperProvider.java index 78183d80893..ffcf542c916 100644 --- a/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsMtRoleMapperProvider.java +++ b/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsMtRoleMapperProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.Grant; @@ -66,6 +67,10 @@ public class IdcsMtRoleMapperProvider extends IdcsRoleMapperProviderBase { .getLogger(IdcsMtRoleMapperProvider.class.getName()); private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); + static { + HelidonFeatures.register("Security", "Role-Mapper", "IDCS-Multitenant"); + } + private final TokenHandler idcsTenantTokenHandler; private final TokenHandler idcsAppNameTokenHandler; private final EvictableCache> cache; diff --git a/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsRoleMapperProvider.java b/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsRoleMapperProvider.java index 2ce0c381537..9cfdf84cc41 100644 --- a/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsRoleMapperProvider.java +++ b/security/providers/idcs-mapper/src/main/java/io/helidon/security/providers/idcs/mapper/IdcsRoleMapperProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; import io.helidon.security.Grant; @@ -48,6 +49,10 @@ public class IdcsRoleMapperProvider extends IdcsRoleMapperProviderBase implements SubjectMappingProvider { private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); + static { + HelidonFeatures.register("Security", "Role-Mapper", "IDCS"); + } + private final EvictableCache> roleCache; private final WebTarget assertEndpoint; diff --git a/security/providers/jwt/src/main/java/io/helidon/security/providers/jwt/JwtProvider.java b/security/providers/jwt/src/main/java/io/helidon/security/providers/jwt/JwtProvider.java index 10ac750e5ef..987bdcbfd84 100644 --- a/security/providers/jwt/src/main/java/io/helidon/security/providers/jwt/JwtProvider.java +++ b/security/providers/jwt/src/main/java/io/helidon/security/providers/jwt/JwtProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import java.util.logging.Logger; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.common.configurable.Resource; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; @@ -68,6 +69,10 @@ public final class JwtProvider extends SynchronousProvider implements Authentica */ public static final String EP_PROPERTY_OUTBOUND_USER = "io.helidon.security.outbound.user"; + static { + HelidonFeatures.register("Security", "Authentication", "JWT"); + } + private final boolean optional; private final boolean authenticate; private final boolean propagate; @@ -116,6 +121,10 @@ private JwtProvider(Builder builder) { if (!verifySignature) { LOGGER.info("JWT Signature validation is disabled. Any JWT will be accepted."); } + + if (propagate) { + HelidonFeatures.register("Security", "Outbound", "JWT"); + } } /** diff --git a/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcProvider.java b/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcProvider.java index 181773faa07..8dfc2510ee6 100644 --- a/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcProvider.java +++ b/security/providers/oidc/src/main/java/io/helidon/security/providers/oidc/OidcProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ import javax.ws.rs.core.Response; import io.helidon.common.Errors; +import io.helidon.common.HelidonFeatures; import io.helidon.common.http.Http; import io.helidon.config.Config; import io.helidon.security.AuthenticationResponse; @@ -88,6 +89,10 @@ public final class OidcProvider extends SynchronousProvider implements AuthenticationProvider, OutboundSecurityProvider { private static final Logger LOGGER = Logger.getLogger(OidcProvider.class.getName()); + static { + HelidonFeatures.register("Security", "Authentication", "OIDC"); + } + private final OidcConfig oidcConfig; private final TokenHandler paramHeaderHandler; @@ -155,6 +160,10 @@ private OidcProvider(Builder builder, OidcOutboundConfig oidcOutboundConfig) { } }; } + + if (propagate) { + HelidonFeatures.register("Security", "Outbound", "OIDC"); + } } /** diff --git a/security/security/src/main/java/io/helidon/security/Security.java b/security/security/src/main/java/io/helidon/security/Security.java index 29599208858..bf1ca501219 100644 --- a/security/security/src/main/java/io/helidon/security/Security.java +++ b/security/security/src/main/java/io/helidon/security/Security.java @@ -40,6 +40,8 @@ import java.util.logging.Logger; import java.util.stream.Collectors; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.configurable.ThreadPoolSupplier; import io.helidon.config.Config; import io.helidon.security.internal.SecurityAuditEvent; @@ -92,6 +94,10 @@ public class Security { private static final Logger LOGGER = Logger.getLogger(Security.class.getName()); + static { + HelidonFeatures.register(HelidonFlavor.SE, "Security"); + } + private final Collection> annotations = new LinkedList<>(); private final List> auditors = new LinkedList<>(); private final Optional subjectMappingProvider; diff --git a/tests/integration/native-image/mp-1/src/main/resources/META-INF/microprofile-config.properties b/tests/integration/native-image/mp-1/src/main/resources/META-INF/microprofile-config.properties index 4f00d83526f..118d0982169 100644 --- a/tests/integration/native-image/mp-1/src/main/resources/META-INF/microprofile-config.properties +++ b/tests/integration/native-image/mp-1/src/main/resources/META-INF/microprofile-config.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,4 +17,4 @@ app.message=Properties message app.jaxrs.message=JAX-RS MP message app.jaxrs.number=42 - +features.print-details=true diff --git a/tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerTracerBuilder.java b/tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerTracerBuilder.java index adafff094e8..ae9f30f0fcd 100644 --- a/tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerTracerBuilder.java +++ b/tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerTracerBuilder.java @@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.tracing.TracerBuilder; @@ -155,6 +156,10 @@ public class JaegerTracerBuilder implements TracerBuilder { static final int DEFAULT_HTTP_PORT = 14268; static final String DEFAULT_HTTP_PATH = "/api/traces"; + static { + HelidonFeatures.register("Tracing", "Jaeger"); + } + private final Map tags = new HashMap<>(); private final List propagations = new ArrayList<>(); private String serviceName; diff --git a/tracing/jersey-client/src/main/java/io/helidon/tracing/jersey/client/ClientTracingFilter.java b/tracing/jersey-client/src/main/java/io/helidon/tracing/jersey/client/ClientTracingFilter.java index fce3e958dbb..0d76d992fcf 100644 --- a/tracing/jersey-client/src/main/java/io/helidon/tracing/jersey/client/ClientTracingFilter.java +++ b/tracing/jersey-client/src/main/java/io/helidon/tracing/jersey/client/ClientTracingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ import javax.ws.rs.client.ClientResponseFilter; import javax.ws.rs.core.MultivaluedMap; +import io.helidon.common.HelidonFeatures; import io.helidon.common.context.Contexts; import io.helidon.tracing.config.SpanTracingConfig; import io.helidon.tracing.config.TracingConfigUtil; @@ -134,13 +135,16 @@ public class ClientTracingFilter implements ClientRequestFilter, ClientResponseF */ public static final String X_REQUEST_ID = "x-request-id"; - static final String SPAN_PROPERTY_NAME = ClientTracingFilter.class.getName() + ".span"; private static final List PROPAGATED_HEADERS = List.of(X_REQUEST_ID, X_OT_SPAN_CONTEXT); private static final int HTTP_STATUS_ERROR_THRESHOLD = 400; private static final int HTTP_STATUS_SERVER_ERROR_THRESHOLD = 500; + static { + HelidonFeatures.register("Tracing", "Integration", "Jersey Client"); + } + private final Optional tracerProvider; /** diff --git a/tracing/jersey/src/main/java/io/helidon/tracing/jersey/AbstractTracingFilter.java b/tracing/jersey/src/main/java/io/helidon/tracing/jersey/AbstractTracingFilter.java index 5c15c298347..f5596949ac7 100644 --- a/tracing/jersey/src/main/java/io/helidon/tracing/jersey/AbstractTracingFilter.java +++ b/tracing/jersey/src/main/java/io/helidon/tracing/jersey/AbstractTracingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.container.PreMatching; +import io.helidon.common.HelidonFeatures; import io.helidon.common.context.Context; import io.helidon.common.context.Contexts; import io.helidon.tracing.config.SpanTracingConfig; @@ -51,6 +52,10 @@ public abstract class AbstractTracingFilter implements ContainerRequestFilter, C private static final String SPAN_PROPERTY = AbstractTracingFilter.class.getName() + ".span"; private static final String SPAN_SCOPE_PROPERTY = AbstractTracingFilter.class.getName() + ".spanScope"; + static { + HelidonFeatures.register("Tracing", "Integration", "Jersey"); + } + @Override public void filter(ContainerRequestContext requestContext) { if (!tracingEnabled(requestContext)) { diff --git a/tracing/tracing/src/main/java/io/helidon/tracing/TracerProviderHelper.java b/tracing/tracing/src/main/java/io/helidon/tracing/TracerProviderHelper.java index 185b211985f..f05f2b4e2ff 100644 --- a/tracing/tracing/src/main/java/io/helidon/tracing/TracerProviderHelper.java +++ b/tracing/tracing/src/main/java/io/helidon/tracing/TracerProviderHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ import java.util.Iterator; import java.util.ServiceLoader; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.serviceloader.HelidonServiceLoader; import io.helidon.tracing.spi.TracerProvider; @@ -28,6 +30,10 @@ final class TracerProviderHelper { private static final ServiceLoader SYSTEM_LOADER = ServiceLoader.load(TracerProvider.class); private static final HelidonServiceLoader SERVICE_LOADER = HelidonServiceLoader.create(SYSTEM_LOADER); + static { + HelidonFeatures.register(HelidonFlavor.SE, "Tracing"); + } + private TracerProviderHelper() { } diff --git a/tracing/zipkin/src/main/java/io/helidon/tracing/zipkin/ZipkinTracerBuilder.java b/tracing/zipkin/src/main/java/io/helidon/tracing/zipkin/ZipkinTracerBuilder.java index f5ec4f256f0..4ef90220664 100644 --- a/tracing/zipkin/src/main/java/io/helidon/tracing/zipkin/ZipkinTracerBuilder.java +++ b/tracing/zipkin/src/main/java/io/helidon/tracing/zipkin/ZipkinTracerBuilder.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.logging.Logger; +import io.helidon.common.HelidonFeatures; import io.helidon.config.Config; import io.helidon.tracing.Tag; import io.helidon.tracing.TracerBuilder; @@ -113,6 +114,10 @@ public class ZipkinTracerBuilder implements TracerBuilder { static final Version DEFAULT_VERSION = Version.V2; static final boolean DEFAULT_ENABLED = true; + static { + HelidonFeatures.register("Tracing", "Zipkin"); + } + private final List> tags = new LinkedList<>(); private String serviceName; private String protocol = DEFAULT_PROTOCOL; diff --git a/webserver/access-log/src/main/java/io/helidon/webserver/accesslog/AccessLogSupport.java b/webserver/access-log/src/main/java/io/helidon/webserver/accesslog/AccessLogSupport.java index 0bd73d6afe3..2857cd56401 100644 --- a/webserver/access-log/src/main/java/io/helidon/webserver/accesslog/AccessLogSupport.java +++ b/webserver/access-log/src/main/java/io/helidon/webserver/accesslog/AccessLogSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.config.Config; import io.helidon.webserver.Routing; import io.helidon.webserver.ServerRequest; @@ -44,6 +46,11 @@ public final class AccessLogSupport implements Service { */ public static final String DEFAULT_LOGGER_NAME = "io.helidon.webserver.AccessLog"; private static final Pattern HEADER_ENTRY_PATTERN = Pattern.compile("%\\{(.*?)}i"); + + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer", "AccessLog"); + } + private final List logFormat; private final Logger logger; private final boolean enabled; diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/NettyWebServer.java b/webserver/webserver/src/main/java/io/helidon/webserver/NettyWebServer.java index aa9be9867b4..c31a3608c8e 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/NettyWebServer.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/NettyWebServer.java @@ -94,7 +94,7 @@ class NettyWebServer implements WebServer { Map namedRoutings) { Set> sockets = config.sockets().entrySet(); - HelidonFeatures.print(HelidonFlavor.SE); + HelidonFeatures.print(HelidonFlavor.SE, config.printFeatureDetails()); this.bossGroup = new NioEventLoopGroup(sockets.size()); this.workerGroup = config.workersCount() <= 0 ? new NioEventLoopGroup() : new NioEventLoopGroup(config.workersCount()); // the contextual registry needs to be created as a different type is expected. Once we remove ContextualRegistry diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/ServerBasicConfig.java b/webserver/webserver/src/main/java/io/helidon/webserver/ServerBasicConfig.java index 40e8ce7cab9..0c6f7a58863 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/ServerBasicConfig.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/ServerBasicConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ class ServerBasicConfig implements ServerConfiguration { private final Map socketConfigs; private final ExperimentalConfiguration experimental; private final ContextualRegistry context; + private final boolean printFeatureDetails; /** * Creates new instance. @@ -51,6 +52,7 @@ class ServerBasicConfig implements ServerConfiguration { this.tracer = builder.tracer(); this.experimental = builder.experimental(); this.context = builder.context(); + this.printFeatureDetails = builder.printFeatureDetails(); HashMap map = new HashMap<>(builder.sockets()); map.put(ServerConfiguration.DEFAULT_SOCKET_NAME, this.socketConfig); @@ -117,6 +119,11 @@ public Context context() { return context; } + @Override + public boolean printFeatureDetails() { + return printFeatureDetails; + } + static class SocketConfig implements SocketConfiguration { private final int port; diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/ServerConfiguration.java b/webserver/webserver/src/main/java/io/helidon/webserver/ServerConfiguration.java index 52a00b0b379..875b0cab137 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/ServerConfiguration.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/ServerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -181,6 +181,13 @@ default SocketConfiguration socket(String name) { */ ExperimentalConfiguration experimental(); + /** + * Whether to print details of {@link io.helidon.common.HelidonFeatures}. + * + * @return whether to print details + */ + boolean printFeatureDetails(); + /** * Checks if HTTP/2 is enabled in config. * @@ -231,6 +238,7 @@ final class Builder implements io.helidon.common.Builder { private Tracer tracer; private ExperimentalConfiguration experimental; private ContextualRegistry context; + private boolean printFeatureDetails; private Builder() { } @@ -444,6 +452,18 @@ public Builder experimental(ExperimentalConfiguration experimental) { return this; } + /** + * Set to {@code true} to print detailed feature information on startup. + * + * @param print whether to print details or not + * @return updated builder instance + * @see io.helidon.common.HelidonFeatures + */ + public Builder printFeatureDetails(boolean print) { + this.printFeatureDetails = print; + return this; + } + /** * Configure the application scoped context to be used as a parent for webserver request contexts. * @param context top level context @@ -485,6 +505,7 @@ public Builder config(Config config) { configureSocket(config, defaultSocketBuilder); config.get("workers").asInt().ifPresent(this::workersCount); + config.get("features.print-details").asBoolean().ifPresent(this::printFeatureDetails); // sockets Config socketsConfig = config.get("sockets"); @@ -597,5 +618,9 @@ ExperimentalConfiguration experimental() { ContextualRegistry context() { return context; } + + boolean printFeatureDetails() { + return printFeatureDetails; + } } } diff --git a/webserver/webserver/src/main/java/io/helidon/webserver/WebServer.java b/webserver/webserver/src/main/java/io/helidon/webserver/WebServer.java index fd03576378f..a3ab2623f10 100644 --- a/webserver/webserver/src/main/java/io/helidon/webserver/WebServer.java +++ b/webserver/webserver/src/main/java/io/helidon/webserver/WebServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ import java.util.function.Supplier; import java.util.stream.Collectors; +import io.helidon.common.HelidonFeatures; +import io.helidon.common.HelidonFlavor; import io.helidon.common.http.ContextualRegistry; /** @@ -216,6 +218,9 @@ static Builder builder(Routing routing) { * sockets and optional multiple routings. */ final class Builder implements io.helidon.common.Builder { + static { + HelidonFeatures.register(HelidonFlavor.SE, "WebServer"); + } private final Map routings = new HashMap<>(); private final Routing defaultRouting;