class Gateway implements SmartLifecycle {

    @Override
    public void start() {
        NettyServerBuilder serverBuilder = NettyServerBuilder.forPort(routingConfiguration.getPort())
                                                             .permitKeepAliveWithoutCalls(true)
                                                             .permitKeepAliveTime(routingConfiguration.getMinKeepAliveTime(), TimeUnit.MILLISECONDS);


        if( routingConfiguration.getMaxMessageSize() > 0) {
            serverBuilder.maxInboundMessageSize(routingConfiguration.getMaxMessageSize());
        }

        String sslMessage = "no SSL";
        if( routingConfiguration.getSsl() != null && routingConfiguration.getSsl().isEnabled()) {
            if( routingConfiguration.getSsl().getCertChainFile() == null) {
                throw new RuntimeException("axoniq.axonserver.ssl.cert-chain-file");
            }
            if( routingConfiguration.getSsl().getPrivateKeyFile() == null) {
                throw new RuntimeException("axoniq.axonserver.ssl.private-key-file");
            }
            serverBuilder.useTransportSecurity(new File(routingConfiguration.getSsl().getCertChainFile()),
                    new File(routingConfiguration.getSsl().getPrivateKeyFile()));
            sslMessage = "SSL enabled";
        }

        axonServerClientServices.forEach(serverBuilder::addService);


        // Note that the last interceptor is executed first
        serverBuilder.intercept(new GrpcBufferingInterceptor(routingConfiguration.getGrpcBufferedMessages()));
        if( routingConfiguration.getAccesscontrol().isEnabled()) {
            serverBuilder.intercept(new AuthenticationInterceptor(axonServerAccessController));
        }
        serverBuilder.intercept(new LicenseInterceptor(licenseAccessController));
        serverBuilder.intercept(new ContextInterceptor());

        if( routingConfiguration.getKeepAliveTime() > 0) {
            serverBuilder.keepAliveTime(routingConfiguration.getKeepAliveTime(), TimeUnit.MILLISECONDS)
                         .keepAliveTimeout(routingConfiguration.getKeepAliveTimeout(), TimeUnit.MILLISECONDS);
        }
        serverBuilder.executor(Executors.newFixedThreadPool(routingConfiguration.getExecutorThreadCount(),
                                                            new CustomizableThreadFactory("grpc-executor-")));

        server = serverBuilder.build();

        try {
            server.start();

            logger.info("Axon Server Gateway started on port: {} - {}", routingConfiguration.getPort(), sslMessage);

            started = true;
        } catch (IOException e) {
            logger.error("Starting Axon Server Gateway failed - {}", e.getMessage(), e);
        }
    }

    public  Gateway(MessagingPlatformConfiguration messagingPlatformConfiguration, List<AxonServerClientService> axonServerClientServices,
                   AxonServerAccessController axonServerAccessController, LicenseAccessController licenseAccessController);

}