All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.linecorp.armeria.server.thrift.THttpServiceBuilder Maven / Gradle / Ivy

Go to download

Asynchronous HTTP/2 RPC/REST client/server library built on top of Java 8, Netty, Thrift and gRPC (armeria-thrift0.9)

The newest version!
/*
 * 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.server.thrift;

import static java.util.Objects.requireNonNull;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimaps;

import com.linecorp.armeria.common.RpcResponse;
import com.linecorp.armeria.common.SerializationFormat;
import com.linecorp.armeria.common.annotation.Nullable;
import com.linecorp.armeria.common.thrift.ThriftProtocolFactoryProvider;
import com.linecorp.armeria.common.thrift.ThriftSerializationFormats;
import com.linecorp.armeria.server.RpcService;
import com.linecorp.armeria.server.ServiceRequestContext;

/**
 * A fluent builder to build an instance of {@link THttpService}. This builder allows to bind multiple thrift
 * service implementations along with mixing TMultiplexed protocol to a route.
 * 

Example

*
{@code
 * Server server =
 *     Server.builder()
 *           .http(8080)
 *           .service("/", THttpService.builder()
 *                                     .addService(new FooService())              // foo() method
 *                                     .addService(new BarService())              // bar() method
 *                                     .addService("foobar", new FooBarService()) // TMultiplexed service
 *                                     .build())
 *           .build();
 * }
* *

When the thrift request has a method {@code foo()} then {@code FooService.foo()} handles the request and * similarly when thrift request has a method {@code bar()} then {@code BarService.bar()} handles the request. * And when the service name is "foobar" then FooBarService

* * @see THttpService * @see ThriftCallService */ public final class THttpServiceBuilder { private static final BiFunction defaultExceptionHandler = (ctx, cause) -> RpcResponse.ofFailure(cause); private final ImmutableListMultimap.Builder implementationsBuilder = ImmutableListMultimap.builder(); private SerializationFormat defaultSerializationFormat = ThriftSerializationFormats.BINARY; private Set otherSerializationFormats = ThriftSerializationFormats.values(); private boolean createOtherSerializations = true; @Nullable private Function decoratorFunction; private BiFunction exceptionHandler = defaultExceptionHandler; THttpServiceBuilder() { } /** * Adds a new {@code TMultiplexed} service to the builder. * * @param name name of the service. * @param implementation an implementation of {@code *.Iface} or {@code *.AsyncIface} service interface * generated by the Apache Thrift compiler. */ public THttpServiceBuilder addService(String name, Object implementation) { implementationsBuilder.put(name, implementation); return this; } /** * Adds a new service implementation to the builder. * * @param implementation an implementation of {@code *.Iface} or {@code *.AsyncIface} service interface * generated by the Apache Thrift compiler */ public THttpServiceBuilder addService(Object implementation) { return addService("", implementation); } /** * Adds other {@link SerializationFormat} to the builder. By default, all {@link SerializationFormat}s in * {@link ThriftSerializationFormats} are supported. If nothing is specified then they are added. * To add a new custom Thrift serialization format, * define a new SPI {@link ThriftProtocolFactoryProvider}. * *

Currently, the only way to specify a serialization format at request time is by using the HTTP session * protocol and setting the {@code "Content-Type"} header to the appropriate * {@link SerializationFormat#mediaType()}. */ public THttpServiceBuilder otherSerializationFormats(SerializationFormat otherSerializationFormat) { requireNonNull(otherSerializationFormat, "otherSerializationFormat"); return otherSerializationFormats(ImmutableList.of(otherSerializationFormat)); } /** * Adds other {@link SerializationFormat}s to the builder. If nothing is specified then all * {@link SerializationFormat}s returned by {@link ThriftSerializationFormats#values()} * are added. * *

Currently, the only way to specify a serialization format at request time is by using the HTTP session * protocol and setting the {@code "Content-Type"} header to the appropriate * {@link SerializationFormat#mediaType()}. */ public THttpServiceBuilder otherSerializationFormats( Iterable otherSerializationFormats) { requireNonNull(otherSerializationFormats, "otherSerializationFormats"); if (createOtherSerializations) { this.otherSerializationFormats = new LinkedHashSet<>(); createOtherSerializations = false; } otherSerializationFormats.forEach(this.otherSerializationFormats::add); return this; } /** * Adds the default serialization format which will be used when the client does not specify one in * request. * *

Currently, the only way to specify a serialization format is by using the HTTP session * protocol and setting the {@code "Content-Type"} header to the appropriate * {@link SerializationFormat#mediaType()}. */ public THttpServiceBuilder defaultSerializationFormat(SerializationFormat defaultSerializationFormat) { requireNonNull(defaultSerializationFormat, "defaultSerializationFormat"); this.defaultSerializationFormat = defaultSerializationFormat; return this; } /** * Sets the {@link BiFunction} that returns an {@link RpcResponse} using the given {@link Throwable} * and {@link ServiceRequestContext}. */ public THttpServiceBuilder exceptionHandler( BiFunction exceptionHandler) { this.exceptionHandler = requireNonNull(exceptionHandler, "exceptionHandler"); return this; } /** * A {@code Function} to decorate the {@link RpcService}. */ public THttpServiceBuilder decorate(Function decoratorFunction) { requireNonNull(decoratorFunction, "decoratorFunction"); if (this.decoratorFunction == null) { this.decoratorFunction = decoratorFunction; } else { this.decoratorFunction = this.decoratorFunction.andThen(decoratorFunction); } return this; } private RpcService decorate(RpcService service) { if (decoratorFunction != null) { return service.decorate(decoratorFunction); } return service; } /** * Builds a new instance of {@link THttpService}. */ public THttpService build() { @SuppressWarnings("UnstableApiUsage") final Map> implementations = Multimaps.asMap(implementationsBuilder.build()); final ThriftCallService tcs = ThriftCallService.of(implementations); return build0(tcs); } /** * Returns a newly-created {@link THttpService} decorator with the properties of this builder. */ public Function newDecorator() { return this::build0; } private THttpService build0(RpcService tcs) { final ImmutableSet.Builder builder = ImmutableSet.builder(); builder.add(defaultSerializationFormat); builder.addAll(otherSerializationFormats); return new THttpService(decorate(tcs), defaultSerializationFormat, builder.build(), exceptionHandler); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy