Skip to content

Commit

Permalink
Add secret property to set the servlet container to sync mode
Browse files Browse the repository at this point in the history
  • Loading branch information
timyates committed Aug 21, 2023
1 parent 5df65a8 commit 6dd7cb9
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
import org.eclipse.jetty.util.ssl.SslContextFactory;

import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.function.Function;
Expand All @@ -53,6 +56,8 @@
@Factory
public class JettyFactory extends ServletServerFactory {

private static final Logger LOG = LoggerFactory.getLogger(JettyFactory.class);

public static final String RESOURCE_BASE = "resourceBase";
private final JettyConfiguration jettyConfiguration;

Expand Down Expand Up @@ -158,7 +163,12 @@ public Resource newResource(String urlOrPath) throws IOException {
servletHolder,
configuration.getMapping()
);
servletHolder.setAsyncSupported(true);

Boolean isAsync = applicationContext.getEnvironment().getProperty("micronaut.server.testing.async", Boolean.class, true);
if (Boolean.FALSE.equals(isAsync)) {
LOG.warn("Async support disabled for testing purposes.");
}
servletHolder.setAsyncSupported(isAsync);

configuration.getMultipartConfigElement().ifPresent(multipartConfiguration ->
servletHolder.getRegistration().setMultipartConfig(multipartConfiguration)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.micronaut.servlet.jetty

import groovy.transform.Canonical
import io.micronaut.context.annotation.Property
import io.micronaut.context.annotation.Requires
import io.micronaut.core.annotation.AnnotationMetadata
import io.micronaut.core.annotation.Introspected
import io.micronaut.core.annotation.NonNull
import io.micronaut.http.MutableHttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.servlet.http.ServletExchange
import io.micronaut.servlet.http.ServletHttpResponse
import io.micronaut.servlet.http.ServletResponseEncoder
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import jakarta.inject.Singleton
import org.reactivestreams.Publisher
import reactor.core.publisher.Flux
import spock.lang.Specification

@MicronautTest
@Property(name = "spec.name", value = SPEC_NAME)
@Property(name = "micronaut.server.testing.async", value = "false")
class JettyResponseEncoderSpec extends Specification {

private static final String SPEC_NAME = "JettyResponseEncoderSpec"

@Inject
@Client("/")
HttpClient client

void "custom encoder applied once"() {
when:
def response = client.toBlocking().exchange("/test", String)

then:
response.body() == "SRE{bar}"
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Controller
static class TestController {

@Get("/test")
SomeResponseType test() {
new SomeResponseType(foo: "bar")
}
}

@Canonical
@Introspected
static class SomeResponseType {
String foo

@Override
String toString() {
"NOPE!"
}
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Singleton
static class SomeResponseEncoder implements ServletResponseEncoder<SomeResponseType> {
@Override
Class<SomeResponseType> getResponseType() {
return SomeResponseType.class
}

@Override
Publisher<MutableHttpResponse<?>> encode(@NonNull ServletExchange<?, ?> exchange, AnnotationMetadata annotationMetadata, @NonNull SomeResponseType value) {
ServletHttpResponse<?, ?> response = exchange.getResponse().contentType("text/plain")
response.getOutputStream() << "SRE{$value.foo}"
Flux.just(response)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Factory for the {@link Tomcat} instance.
Expand All @@ -46,6 +48,8 @@
@Factory
public class TomcatFactory extends ServletServerFactory {

private static final Logger LOG = LoggerFactory.getLogger(TomcatFactory.class);

/**
* Default constructor.
*
Expand Down Expand Up @@ -101,7 +105,12 @@ protected Tomcat tomcatServer(Connector connector, MicronautServletConfiguration
configuration.getName(),
new DefaultMicronautServlet(getApplicationContext())
);
servlet.setAsyncSupported(true);

Boolean isAsync = getApplicationContext().getEnvironment().getProperty("micronaut.server.testing.async", Boolean.class, true);
if (Boolean.FALSE.equals(isAsync)) {
LOG.warn("Async support disabled for testing purposes.");
}
servlet.setAsyncSupported(isAsync);
servlet.addMapping(configuration.getMapping());
getStaticResourceConfigurations().forEach(config ->
servlet.addMapping(config.getMapping())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.micronaut.servlet.tomcat

import groovy.transform.Canonical
import io.micronaut.context.annotation.Property
import io.micronaut.context.annotation.Requires
import io.micronaut.core.annotation.AnnotationMetadata
import io.micronaut.core.annotation.Introspected
import io.micronaut.core.annotation.NonNull
import io.micronaut.http.MutableHttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.servlet.http.ServletExchange
import io.micronaut.servlet.http.ServletHttpResponse
import io.micronaut.servlet.http.ServletResponseEncoder
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import jakarta.inject.Singleton
import org.reactivestreams.Publisher
import reactor.core.publisher.Flux
import spock.lang.Specification

@MicronautTest
@Property(name = "spec.name", value = SPEC_NAME)
@Property(name = "micronaut.server.testing.async", value = "false")
class TomcatResponseEncoderSpec extends Specification {

private static final String SPEC_NAME = "JettyResponseEncoderSpec"

@Inject
@Client("/")
HttpClient client

void "custom encoder applied once"() {
when:
def response = client.toBlocking().exchange("/test", String)

then:
response.body() == "SRE{bar}"
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Controller
static class TestController {

@Get("/test")
SomeResponseType test() {
new SomeResponseType(foo: "bar")
}
}

@Canonical
@Introspected
static class SomeResponseType {
String foo

@Override
String toString() {
"NOPE!"
}
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Singleton
static class SomeResponseEncoder implements ServletResponseEncoder<SomeResponseType> {
@Override
Class<SomeResponseType> getResponseType() {
return SomeResponseType.class
}

@Override
Publisher<MutableHttpResponse<?>> encode(@NonNull ServletExchange<?, ?> exchange, AnnotationMetadata annotationMetadata, @NonNull SomeResponseType value) {
ServletHttpResponse<?, ?> response = exchange.getResponse().contentType("text/plain")
response.getOutputStream() << "SRE{$value.foo}"
Flux.just(response)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import io.undertow.server.handlers.PathHandler;
import io.undertow.servlet.Servlets;
import io.undertow.servlet.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnio.Option;
import org.xnio.Options;

Expand All @@ -52,6 +54,8 @@
@Factory
public class UndertowFactory extends ServletServerFactory {

private static final Logger LOG = LoggerFactory.getLogger(UndertowFactory.class);

private final UndertowConfiguration configuration;

/**
Expand Down Expand Up @@ -218,7 +222,11 @@ public void release() {
}
}
);
servletInfo.setAsyncSupported(true);
Boolean isAsync = getApplicationContext().getEnvironment().getProperty("micronaut.server.testing.async", Boolean.class, true);
if (Boolean.FALSE.equals(isAsync)) {
LOG.warn("Async support disabled for testing purposes.");
}
servletInfo.setAsyncSupported(isAsync);
servletInfo.addMapping(servletConfiguration.getMapping());
getStaticResourceConfigurations().forEach(config -> {
servletInfo.addMapping(config.getMapping());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.micronaut.servlet.undertow

import groovy.transform.Canonical
import io.micronaut.context.annotation.Property
import io.micronaut.context.annotation.Requires
import io.micronaut.core.annotation.AnnotationMetadata
import io.micronaut.core.annotation.Introspected
import io.micronaut.core.annotation.NonNull
import io.micronaut.http.MutableHttpResponse
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.servlet.http.ServletExchange
import io.micronaut.servlet.http.ServletHttpResponse
import io.micronaut.servlet.http.ServletResponseEncoder
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import jakarta.inject.Singleton
import org.reactivestreams.Publisher
import reactor.core.publisher.Flux
import spock.lang.Specification

@MicronautTest
@Property(name = "spec.name", value = SPEC_NAME)
@Property(name = "micronaut.server.testing.async", value = "false")
class UndertowResponseEncoderSpec extends Specification {

private static final String SPEC_NAME = "JettyResponseEncoderSpec"

@Inject
@Client("/")
HttpClient client

void "custom encoder applied once"() {
when:
def response = client.toBlocking().exchange("/test", String)

then:
response.body() == "SRE{bar}"
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Controller
static class TestController {

@Get("/test")
SomeResponseType test() {
new SomeResponseType(foo: "bar")
}
}

@Canonical
@Introspected
static class SomeResponseType {
String foo

@Override
String toString() {
"NOPE!"
}
}

@Requires(property = "spec.name", value = SPEC_NAME)
@Singleton
static class SomeResponseEncoder implements ServletResponseEncoder<SomeResponseType> {
@Override
Class<SomeResponseType> getResponseType() {
return SomeResponseType.class
}

@Override
Publisher<MutableHttpResponse<?>> encode(@NonNull ServletExchange<?, ?> exchange, AnnotationMetadata annotationMetadata, @NonNull SomeResponseType value) {
ServletHttpResponse<?, ?> response = exchange.getResponse().contentType("text/plain")
response.getOutputStream() << "SRE{$value.foo}"
Flux.just(response)
}
}
}

0 comments on commit 6dd7cb9

Please sign in to comment.