Skip to content

Commit

Permalink
Recognize Consumer<ServerBuilder> beans for spring autoconfiguration (#…
Browse files Browse the repository at this point in the history
…2070)

I think it's useful to be able to customize with spring without using custom types, for example to allow creating a plugin module that just configures a server without needing to worry about armeria-spring. It's sort of similar to how Spring supports both custom annotations and `javax.inject` annotaions. 

Idea came up in openzipkin-contrib/zipkin-storage-kafka#38
  • Loading branch information
anuraaga authored and trustin committed Sep 16, 2019
1 parent 60c5a17 commit d89c801
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
Expand Up @@ -27,6 +27,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -70,6 +71,7 @@ public Server armeriaServer(
Optional<MeterIdPrefixFunctionFactory> meterIdPrefixFunctionFactory,
Optional<List<HealthChecker>> healthCheckers,
Optional<List<ArmeriaServerConfigurator>> armeriaServerConfigurators,
Optional<List<Consumer<ServerBuilder>>> armeriaServerBuilderConsumers,
Optional<List<ThriftServiceRegistrationBean>> thriftServiceRegistrationBeans,
Optional<List<GrpcServiceRegistrationBean>> grpcServiceRegistrationBean,
Optional<List<HttpServiceRegistrationBean>> httpServiceRegistrationBeans,
Expand Down Expand Up @@ -123,6 +125,10 @@ public Server armeriaServer(
configurators -> configurators.forEach(
configurator -> configurator.configure(server)));

armeriaServerBuilderConsumers.ifPresent(
consumers -> consumers.forEach(
consumer -> consumer.accept(server)));

if (!Strings.isNullOrEmpty(docsPath)) {
server.serviceUnder(docsPath, docServiceBuilder.build());
}
Expand Down
@@ -0,0 +1,84 @@
/*
* Copyright 2019 LINE Corporation
*
* LINE Corporation licenses this file to you 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:
*
* https://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 com.linecorp.armeria.spring;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import javax.inject.Inject;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.DisableOnDebug;
import org.junit.rules.TestRule;
import org.junit.rules.Timeout;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

import com.linecorp.armeria.client.HttpClient;
import com.linecorp.armeria.common.AggregatedHttpResponse;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.spring.ArmeriaAutoConfigurationWithConsumerTest.TestConfiguration;

/**
* This uses {@link ArmeriaAutoConfiguration} for integration tests.
* application-autoConfTest.yml will be loaded with minimal settings to make it work.
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@ActiveProfiles({ "local", "autoConfTest" })
public class ArmeriaAutoConfigurationWithConsumerTest {

@SpringBootApplication
@Import(ArmeriaOkServiceConfiguration.class)
public static class TestConfiguration {
@Bean
public Consumer<ServerBuilder> customizer() {
return sb -> sb.service("/customizer", ((ctx, req) -> HttpResponse.of(HttpStatus.OK)));
}
}

@Rule
public TestRule globalTimeout = new DisableOnDebug(new Timeout(10, TimeUnit.SECONDS));

@Inject
private Server server;

private String newUrl(String scheme) {
final int port = server.activeLocalPort();
return scheme + "://127.0.0.1:" + port;
}

@Test
public void normal() throws Exception {
final HttpClient client = HttpClient.of(newUrl("h1c"));

final HttpResponse response = client.get("/customizer");

final AggregatedHttpResponse msg = response.aggregate().get();
assertThat(msg.status()).isEqualTo(HttpStatus.OK);
}
}

0 comments on commit d89c801

Please sign in to comment.