graylog rest servcie 启动&集成说明

参考处理

  • 模块定义Graylog2Module
protected void addSystemRestResource(Class<?> restResourceClass) {
    systemRestResourceBinder().addBinding().toInstance(restResourceClass);
}
 
private Multibinder<Class<?>> systemRestResourceBinder() {
    return Multibinder.newSetBinder(
            binder(),
            new TypeLiteral<Class<?>>() {},
            Names.named(SYSTEM_REST_RESOURCES)
    );
}
  • 注册类型
@Override
protected void configure() {
    addSystemRestResource(DocumentationBrowserResource.class);
    addSystemRestResource(DocumentationResource.class);
    addSystemRestResource(CodecTypesResource.class);
    addSystemRestResource(InputTypesResource.class);
    addSystemRestResource(LoadBalancerStatusResource.class);
    addSystemRestResource(MetricsResource.class);
    addSystemRestResource(SystemPluginResource.class);
    addSystemRestResource(SystemResource.class);
    addSystemRestResource(ThroughputResource.class);
}
  • jersey 集成
    JerseyService 基于buildResourceConfig 使用systemRestResources 定义的服务基于guice 注入,使用的jersey-container-grizzly2-http 模块
 
private ResourceConfig buildResourceConfig(final boolean enableCors,
                                               final Set<Resource> additionalResources) {
        final Map<String, String> packagePrefixes = ImmutableMap.of(
                RESOURCE_PACKAGE_WEB, HttpConfiguration.PATH_WEB,
                "", HttpConfiguration.PATH_API
        );
 
        final ResourceConfig rc = new ResourceConfig()
                .property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true)
                .property(ServerProperties.WADL_FEATURE_DISABLE, true)
                .property(ServerProperties.MEDIA_TYPE_MAPPINGS, mediaTypeMappings())
                .register(new PrefixAddingModelProcessor(packagePrefixes, graylogConfiguration))
                .register(new AuditEventModelProcessor(pluginAuditEventTypes))
                .registerClasses(
                        ShiroSecurityContextFilter.class,
                        ShiroRequestHeadersBinder.class,
                        VerboseCsrfProtectionFilter.class,
                        JacksonJaxbJsonProvider.class,
                        JsonProcessingExceptionMapper.class,
                        JsonMappingExceptionMapper.class,
                        JacksonPropertyExceptionMapper.class,
                        AnyExceptionClassMapper.class,
                        MissingStreamPermissionExceptionMapper.class,
                        WebApplicationExceptionMapper.class,
                        BadRequestExceptionMapper.class,
                        RestAccessLogFilter.class,
                        NodeIdResponseFilter.class,
                        RequestIdFilter.class,
                        XHRFilter.class,
                        NotAuthorizedResponseFilter.class,
                        WebAppNotFoundResponseFilter.class)
                // Replacing this with a lambda leads to missing subtypes - https://github.com/Graylog2/graylog2-server/pull/10617#discussion_r630236360
                .register(new ContextResolver<ObjectMapper>() {
                    @Override
                    public ObjectMapper getContext(Class<?> type) {
                        return objectMapper;
                    }
                })
                .register(new UserContextBinder())
                .register(MultiPartFeature.class)
                .registerClasses(systemRestResources)
                .registerResources(additionalResources);
 
        exceptionMappers.forEach(rc::registerClasses);
        dynamicFeatures.forEach(rc::registerClasses);
        containerResponseFilters.forEach(rc::registerClasses);
        additionalComponents.forEach(rc::registerClasses);
 
        if (enableCors) {
            LOG.info("Enabling CORS for HTTP endpoint");
            rc.registerClasses(CORSFilter.class);
        }
 
        if (LOG.isDebugEnabled()) {
            rc.registerClasses(PrintModelProcessor.class);
        }
 
        return rc;
    }

服务启动

private void startUpApi() throws Exception {
        final Set<Resource> pluginResources = prefixPluginResources(PLUGIN_PREFIX, pluginRestResources);
 
        final SSLEngineConfigurator sslEngineConfigurator = configuration.isHttpEnableTls() ?
                buildSslEngineConfigurator(
                        configuration.getHttpTlsCertFile(),
                        configuration.getHttpTlsKeyFile(),
                        configuration.getHttpTlsKeyPassword()) : null;
 
        final HostAndPort bindAddress = configuration.getHttpBindAddress();
        final String contextPath = configuration.getHttpPublishUri().getPath();
        final URI listenUri = new URI(
                configuration.getUriScheme(),
                null,
                bindAddress.getHost(),
                bindAddress.getPort(),
                isNullOrEmpty(contextPath) ? "/" : contextPath,
                null,
                null
        );
 
        apiHttpServer = setUp(
                listenUri,
                sslEngineConfigurator,
                configuration.getHttpThreadPoolSize(),
                configuration.getHttpSelectorRunnersCount(),
                configuration.getHttpMaxHeaderSize(),
                configuration.isHttpEnableGzip(),
                configuration.isHttpEnableCors(),
                pluginResources);
 
        apiHttpServer.start();
 
        LOG.info("Started REST API at <{}>", configuration.getHttpBindAddress());
    }
 
private HttpServer setUp(URI listenUri,
                             SSLEngineConfigurator sslEngineConfigurator,
                             int threadPoolSize,
                             int selectorRunnersCount,
                             int maxHeaderSize,
                             boolean enableGzip,
                             boolean enableCors,
                             Set<Resource> additionalResources) {
        final ResourceConfig resourceConfig = buildResourceConfig(enableCors, additionalResources);
        final HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(
                listenUri,
                resourceConfig,
                sslEngineConfigurator != null,
                sslEngineConfigurator,
                false);
 
        final NetworkListener listener = httpServer.getListener("grizzly");
        listener.setMaxHttpHeaderSize(maxHeaderSize);
 
        final ExecutorService workerThreadPoolExecutor = instrumentedExecutor(
                "http-worker-executor",
                "http-worker-%d",
                threadPoolSize);
        listener.getTransport().setWorkerThreadPool(workerThreadPoolExecutor);
 
        // The Grizzly default value is equal to `Runtime.getRuntime().availableProcessors()` which doesn't make
        // sense for Graylog because we are not mainly a web server.
        // See "Selector runners count" at https://grizzly.java.net/bestpractices.html for details.
        listener.getTransport().setSelectorRunnersCount(selectorRunnersCount);
 
        listener.setDefaultErrorPageGenerator(errorPageGenerator);
 
        if (enableGzip) {
            final CompressionConfig compressionConfig = listener.getCompressionConfig();
            compressionConfig.setCompressionMode(CompressionConfig.CompressionMode.ON);
            compressionConfig.setCompressionMinSize(512);
        }
 
        return httpServer;
    }

说明

以上是graylog 关于rest api 定义以及启动的简单说明,设计上还是比较方便的,值得学习参考

参考资料

https://github.com/google/guice/wiki/Multibindings
https://eclipse-ee4j.github.io/jersey/
https://github.com/Graylog2/graylog2-server/blob/626be1f0d80506705b5ba41fbea33c2ec0164bc0/graylog2-server/src/main/java/org/graylog2/shared/rest/resources/RestResourcesSharedModule.java
https://github.com/Graylog2/graylog2-server/blob/626be1f0d80506705b5ba41fbea33c2ec0164bc0/graylog2-server/src/main/java/org/graylog2/plugin/inject/Graylog2Module.java
https://github.com/Graylog2/graylog2-server/blob/626be1f0d80506705b5ba41fbea33c2ec0164bc0/graylog2-server/src/main/java/org/graylog2/shared/initializers/JerseyService.java

posted on 2022-10-03 00:08  荣锋亮  阅读(71)  评论(0编辑  收藏  举报

导航