Search in sources :

Example 1 with JaxRsApplication

use of io.helidon.microprofile.server.JaxRsApplication in project helidon by oracle.

the class MPOpenAPIBuilder method buildPerAppFilteredIndexViews.

/**
 * Builds a list of filtered index views, one for each JAX-RS application, sorted by the Application class name to help
 * keep the list of endpoints in the OpenAPI document in a stable order.
 * <p>
 * First, we find all resource, provider, and feature classes present in the index. This is the same for all
 * applications.
 * </p>
 * <p>
 * Each filtered index view is tuned to one JAX-RS application.
 *
 * @return list of {@code FilteredIndexView}s, one per JAX-RS application
 */
private List<FilteredIndexView> buildPerAppFilteredIndexViews() {
    List<JaxRsApplication> jaxRsApplications = jaxRsApplicationsToRun().stream().filter(jaxRsApp -> jaxRsApp.applicationClass().isPresent()).sorted(Comparator.comparing(jaxRsApplication -> jaxRsApplication.applicationClass().get().getName())).collect(Collectors.toList());
    IndexView indexView = singleIndexViewSupplier.get();
    FilteredIndexView viewFilteredByConfig = new FilteredIndexView(indexView, OpenApiConfigImpl.fromConfig(mpConfig));
    Set<String> ancillaryClassNames = ancillaryClassNames(viewFilteredByConfig);
    /*
         * Filter even for a single-application class in case it implements getClasses or getSingletons.
         */
    return jaxRsApplications.stream().map(jaxRsApp -> filteredIndexView(viewFilteredByConfig, jaxRsApplications, jaxRsApp, ancillaryClassNames)).collect(Collectors.toList());
}
Also used : FilteredIndexView(io.smallrye.openapi.runtime.scanner.FilteredIndexView) FilteredIndexView(io.smallrye.openapi.runtime.scanner.FilteredIndexView) CDI(jakarta.enterprise.inject.spi.CDI) JaxRsCdiExtension(io.helidon.microprofile.server.JaxRsCdiExtension) DotName(org.jboss.jandex.DotName) ClassInfo(org.jboss.jandex.ClassInfo) Supplier(java.util.function.Supplier) Level(java.util.logging.Level) Path(jakarta.ws.rs.Path) HashSet(java.util.HashSet) OpenApiConfigImpl(io.smallrye.openapi.api.OpenApiConfigImpl) OpenAPISupport(io.helidon.openapi.OpenAPISupport) AnnotationTarget(org.jboss.jandex.AnnotationTarget) Feature(jakarta.ws.rs.core.Feature) IndexView(org.jboss.jandex.IndexView) Set(java.util.Set) Config(org.eclipse.microprofile.config.Config) Logger(java.util.logging.Logger) Provider(jakarta.ws.rs.ext.Provider) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) OpenApiConfig(io.smallrye.openapi.api.OpenApiConfig) List(java.util.List) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication) AnnotationInstance(org.jboss.jandex.AnnotationInstance) Modifier(java.lang.reflect.Modifier) Application(jakarta.ws.rs.core.Application) Pattern(java.util.regex.Pattern) Comparator(java.util.Comparator) FilteredIndexView(io.smallrye.openapi.runtime.scanner.FilteredIndexView) IndexView(org.jboss.jandex.IndexView) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication)

Example 2 with JaxRsApplication

use of io.helidon.microprofile.server.JaxRsApplication in project helidon by oracle.

the class TracingCdiExtension method prepareTracer.

private void prepareTracer(@Observes @Priority(PLATFORM_BEFORE + 11) @Initialized(ApplicationScoped.class) Object event, BeanManager bm) {
    JaxRsCdiExtension jaxrs = bm.getExtension(JaxRsCdiExtension.class);
    ServerCdiExtension server = bm.getExtension(ServerCdiExtension.class);
    Config config = ((Config) ConfigProvider.getConfig()).get("tracing");
    // we need that `tracing.service` is a required configuration, yet we do not want to just fail
    // if not present. Let's make a "guess" about the service name
    List<JaxRsApplication> jaxRsApps = jaxrs.applicationsToRun();
    String serviceName = jaxrs.serviceName();
    Tracer tracer = TracerBuilder.create(serviceName).config(config).build();
    // tracer is available in global
    Contexts.globalContext().register(tracer);
    server.serverBuilder().tracer(tracer);
    Contexts.context().ifPresent(ctx -> ctx.register(tracer));
    if (tracer.getClass().getName().startsWith("io.opentracing.noop")) {
        Logger.getLogger(TracingCdiExtension.class.getName()).warning("helidon-microprofile-tracing is on the classpath, yet there is no tracer implementation " + "library. Tracing uses a no-op tracer. As a result, no tracing will be configured" + " for WebServer and JAX-RS");
        // no need to register all of this
        return;
    }
    server.serverRoutingBuilder().register(WebTracingConfig.create(config));
    jaxRsApps.forEach(app -> app.resourceConfig().register(MpTracingFilter.class));
}
Also used : Config(io.helidon.config.Config) WebTracingConfig(io.helidon.webserver.WebTracingConfig) Tracer(io.opentracing.Tracer) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication) JaxRsCdiExtension(io.helidon.microprofile.server.JaxRsCdiExtension) ServerCdiExtension(io.helidon.microprofile.server.ServerCdiExtension)

Example 3 with JaxRsApplication

use of io.helidon.microprofile.server.JaxRsApplication in project helidon by oracle.

the class OpenApiCdiExtension method indexFromHarvestedClasses.

private IndexView indexFromHarvestedClasses() throws IOException {
    Indexer indexer = new Indexer();
    annotatedTypes.forEach(c -> addClassToIndexer(indexer, c));
    /*
         * Some apps might be added dynamically, not via annotation processing. Add those classes to the index if they are not
         * already present.
         */
    MPOpenAPIBuilder.jaxRsApplicationsToRun().stream().map(JaxRsApplication::applicationClass).filter(Optional::isPresent).forEach(appClassOpt -> addClassToIndexer(indexer, appClassOpt.get()));
    LOGGER.log(Level.CONFIG, "Using internal Jandex index created from CDI bean discovery");
    Index result = indexer.complete();
    dumpIndex(Level.FINER, result);
    return result;
}
Also used : Indexer(org.jboss.jandex.Indexer) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication) CompositeIndex(org.jboss.jandex.CompositeIndex) Index(org.jboss.jandex.Index)

Example 4 with JaxRsApplication

use of io.helidon.microprofile.server.JaxRsApplication in project helidon by oracle.

the class MPOpenAPIBuilder method filteredIndexView.

/**
 * Creates a {@link io.smallrye.openapi.runtime.scanner.FilteredIndexView} tailored to the specified JAX-RS application.
 * <p>
 *     Use an {@link io.smallrye.openapi.api.OpenApiConfig} instance which (possibly) limits scanning for this application
 *     by excluding classes that are not "relevant" to the specified application. For our purposes, the classes "relevant"
 *     to an application are those:
 * <ul>
 *     <li>returned by the application's {@code getClasses} method, and</li>
 *     <li>inferred from the objects returned from the application's {@code getSingletons} method.</li>
 * </ul>
 *
 * If both methods return empty sets (the default implementation in {@link jakarta.ws.rs.core.Application}), then all
 * resources, providers, and features are considered relevant to the application.
 * <p>
 * In constructing the filtered index view for a JAX-RS application, we also exclude the other JAX-RS application classes.
 * </p>
 *
 * @param viewFilteredByConfig filtered index view based only on MP config
 * @param jaxRsApplications all JAX-RS applications discovered
 * @param jaxRsApp the specific JAX-RS application of interest
 * @param ancillaryClassNames names of resource, provider, and feature classes
 * @return the filtered index view suitable for the specified JAX-RS application
 */
private FilteredIndexView filteredIndexView(FilteredIndexView viewFilteredByConfig, List<JaxRsApplication> jaxRsApplications, JaxRsApplication jaxRsApp, Set<String> ancillaryClassNames) {
    Application app = jaxRsApp.resourceConfig().getApplication();
    Set<String> classesFromGetSingletons = app.getSingletons().stream().map(Object::getClass).map(Class::getName).collect(Collectors.toSet());
    Set<String> classesFromGetClasses = app.getClasses().stream().map(Class::getName).collect(Collectors.toSet());
    String appClassName = toClassName(jaxRsApp);
    Set<String> classesExplicitlyReferenced = new HashSet<>(classesFromGetClasses);
    classesExplicitlyReferenced.addAll(classesFromGetSingletons);
    if (classesExplicitlyReferenced.isEmpty() && jaxRsApplications.size() == 1) {
        // No need to do filtering at all.
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, String.format("No filtering required for %s which reports no explicitly referenced classes and " + "is the only JAX-RS application", appClassName));
        }
        return viewFilteredByConfig;
    }
    // in the OpenAPI document.
    if ((classesFromGetClasses.isEmpty() && (classesFromGetSingletons.isEmpty() || !useJaxRsSemantics)) && jaxRsApplications.size() == 1) {
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, String.format("No filtering required for %s; although it returns a non-empty set from getSingletons, JAX-RS semantics " + "has been turned off for OpenAPI processing using " + USE_JAXRS_SEMANTICS_CONFIG_KEY, appClassName));
        }
        return viewFilteredByConfig;
    }
    /*
         * If the classes to be ignored are A and B, the exclusion regex expression we want for filtering is
         *
         * ^(A|B)$
         *
         * The ^ and $ avoid incorrect prefix/suffix matches.
         */
    Pattern excludePattern = Pattern.compile(classNamesToIgnore(jaxRsApplications, jaxRsApp, ancillaryClassNames, classesExplicitlyReferenced).stream().map(Pattern::quote).collect(Collectors.joining("|", "^(", ")$")));
    // Create a new filtered index view for this application which excludes the irrelevant classes we just identified. Its
    // delegate is the previously-created view based only on the MP configuration.
    FilteredIndexView result = new FilteredIndexView(viewFilteredByConfig, new FilteringOpenApiConfigImpl(mpConfig, excludePattern));
    if (LOGGER.isLoggable(Level.FINE)) {
        String knownClassNames = result.getKnownClasses().stream().map(ClassInfo::toString).sorted().collect(Collectors.joining("," + System.lineSeparator() + "    "));
        LOGGER.log(Level.FINE, String.format("FilteredIndexView for %n" + "  application class %s%n" + "  with explicitly-referenced classes %s%n" + "  yields exclude pattern: %s%n" + "  and known classes: %n  %s", appClassName, classesExplicitlyReferenced, excludePattern, knownClassNames));
    }
    return result;
}
Also used : FilteredIndexView(io.smallrye.openapi.runtime.scanner.FilteredIndexView) Pattern(java.util.regex.Pattern) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication) Application(jakarta.ws.rs.core.Application) HashSet(java.util.HashSet) ClassInfo(org.jboss.jandex.ClassInfo)

Example 5 with JaxRsApplication

use of io.helidon.microprofile.server.JaxRsApplication in project helidon by oracle.

the class JwtAuthCdiExtension method registerProvider.

void registerProvider(@Observes @Initialized(ApplicationScoped.class) @Priority(PLATFORM_BEFORE + 5) Object event, BeanManager bm) {
    // Security extension to update and check builder
    SecurityCdiExtension security = bm.getExtension(SecurityCdiExtension.class);
    if (security.securityBuilder().hasProvider(JwtAuthProviderService.PROVIDER_NAME)) {
        return;
    }
    // JAX-RS extension to get to applications to see if we are needed
    JaxRsCdiExtension jaxrs = bm.getExtension(JaxRsCdiExtension.class);
    boolean notNeeded = jaxrs.applicationsToRun().stream().map(JaxRsApplication::applicationClass).flatMap(Optional::stream).map(clazz -> clazz.getAnnotation(LoginConfig.class)).filter(Objects::nonNull).map(LoginConfig::authMethod).noneMatch("MP-JWT"::equals);
    if (notNeeded) {
        return;
    }
    security.securityBuilder().addProvider(JwtAuthProvider.create(config), JwtAuthProviderService.PROVIDER_NAME);
}
Also used : Dependent(jakarta.enterprise.context.Dependent) Arrays(java.util.Arrays) JsonValue(jakarta.json.JsonValue) JaxRsCdiExtension(io.helidon.microprofile.server.JaxRsCdiExtension) AnnotationLiteral(jakarta.enterprise.util.AnnotationLiteral) ApplicationScoped(jakarta.enterprise.context.ApplicationScoped) AfterDeploymentValidation(jakarta.enterprise.inject.spi.AfterDeploymentValidation) RuntimeStart(io.helidon.microprofile.cdi.RuntimeStart) AnnotatedParameter(jakarta.enterprise.inject.spi.AnnotatedParameter) BeforeBeanDiscovery(jakarta.enterprise.inject.spi.BeforeBeanDiscovery) Map(java.util.Map) DeploymentException(jakarta.enterprise.inject.spi.DeploymentException) JsonObject(jakarta.json.JsonObject) Method(java.lang.reflect.Method) Initialized(jakarta.enterprise.context.Initialized) Claims(org.eclipse.microprofile.jwt.Claims) PLATFORM_BEFORE(jakarta.interceptor.Interceptor.Priority.PLATFORM_BEFORE) BeanManager(jakarta.enterprise.inject.spi.BeanManager) TYPE(java.lang.annotation.ElementType.TYPE) FIELD(java.lang.annotation.ElementType.FIELD) Member(java.lang.reflect.Member) Set(java.util.Set) Objects(java.util.Objects) List(java.util.List) JaxRsApplication(io.helidon.microprofile.server.JaxRsApplication) Type(java.lang.reflect.Type) Optional(java.util.Optional) JsonNumber(jakarta.json.JsonNumber) JsonArray(jakarta.json.JsonArray) SecurityCdiExtension(io.helidon.microprofile.security.SecurityCdiExtension) Observes(jakarta.enterprise.event.Observes) ClaimValue(org.eclipse.microprofile.jwt.ClaimValue) PARAMETER(java.lang.annotation.ElementType.PARAMETER) ProcessInjectionPoint(jakarta.enterprise.inject.spi.ProcessInjectionPoint) Constructor(java.lang.reflect.Constructor) Instance(jakarta.enterprise.inject.Instance) Retention(java.lang.annotation.Retention) LoginConfig(org.eclipse.microprofile.auth.LoginConfig) AnnotatedField(jakarta.enterprise.inject.spi.AnnotatedField) Extension(jakarta.enterprise.inject.spi.Extension) Priority(jakarta.annotation.Priority) LinkedList(java.util.LinkedList) Config(io.helidon.config.Config) InjectionPoint(jakarta.enterprise.inject.spi.InjectionPoint) Claim(org.eclipse.microprofile.jwt.Claim) Target(java.lang.annotation.Target) Nonbinding(jakarta.enterprise.util.Nonbinding) RUNTIME(java.lang.annotation.RetentionPolicy.RUNTIME) METHOD(java.lang.annotation.ElementType.METHOD) ParameterizedType(java.lang.reflect.ParameterizedType) AfterBeanDiscovery(jakarta.enterprise.inject.spi.AfterBeanDiscovery) Annotated(jakarta.enterprise.inject.spi.Annotated) Provider(jakarta.inject.Provider) Qualifier(jakarta.inject.Qualifier) RequestScoped(jakarta.enterprise.context.RequestScoped) JsonString(jakarta.json.JsonString) Optional(java.util.Optional) SecurityCdiExtension(io.helidon.microprofile.security.SecurityCdiExtension) Objects(java.util.Objects) JaxRsCdiExtension(io.helidon.microprofile.server.JaxRsCdiExtension)

Aggregations

JaxRsApplication (io.helidon.microprofile.server.JaxRsApplication)5 JaxRsCdiExtension (io.helidon.microprofile.server.JaxRsCdiExtension)3 Config (io.helidon.config.Config)2 FilteredIndexView (io.smallrye.openapi.runtime.scanner.FilteredIndexView)2 Application (jakarta.ws.rs.core.Application)2 RuntimeStart (io.helidon.microprofile.cdi.RuntimeStart)1 SecurityCdiExtension (io.helidon.microprofile.security.SecurityCdiExtension)1 ServerCdiExtension (io.helidon.microprofile.server.ServerCdiExtension)1 OpenAPISupport (io.helidon.openapi.OpenAPISupport)1 WebTracingConfig (io.helidon.webserver.WebTracingConfig)1 Tracer (io.opentracing.Tracer)1 OpenApiConfig (io.smallrye.openapi.api.OpenApiConfig)1 OpenApiConfigImpl (io.smallrye.openapi.api.OpenApiConfigImpl)1 Priority (jakarta.annotation.Priority)1 ApplicationScoped (jakarta.enterprise.context.ApplicationScoped)1 Dependent (jakarta.enterprise.context.Dependent)1 Initialized (jakarta.enterprise.context.Initialized)1 RequestScoped (jakarta.enterprise.context.RequestScoped)1 Observes (jakarta.enterprise.event.Observes)1 Instance (jakarta.enterprise.inject.Instance)1