blob: 1dbe51e9d4fd064bff4e919baf0edccef020e028 [file] [log] [blame]
David Reiss3f660a42010-08-30 22:05:29 +00001%%
2%% Licensed to the Apache Software Foundation (ASF) under one
3%% or more contributor license agreements. See the NOTICE file
4%% distributed with this work for additional information
5%% regarding copyright ownership. The ASF licenses this file
6%% to you under the Apache License, Version 2.0 (the
7%% "License"); you may not use this file except in compliance
8%% with the License. You may obtain a copy of the License at
9%%
10%% http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing,
13%% software distributed under the License is distributed on an
14%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15%% KIND, either express or implied. See the License for the
16%% specific language governing permissions and limitations
17%% under the License.
18%%
19
20-module(thrift_client_util).
21
22-export([new/4]).
David Robakowskiae971ce2013-08-02 12:16:00 +020023-export([new_multiplexed/3, new_multiplexed/4]).
24
25-type service_name() :: nonempty_string().
26-type service_module() :: atom().
27-type multiplexed_service_map() :: [{ServiceName::service_name(), ServiceModule::service_module()}].
David Reiss3f660a42010-08-30 22:05:29 +000028
29%%
30%% Splits client options into client, protocol, and transport options
31%%
32%% split_options([Options...]) -> {ProtocolOptions, TransportOptions}
33%%
34split_options(Options) ->
35 split_options(Options, [], []).
36
37split_options([], ProtoIn, TransIn) ->
38 {ProtoIn, TransIn};
39
40split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
41 when OptKey =:= strict_read;
Nobuaki Sukegawab31f0902015-11-01 17:00:34 +090042 OptKey =:= strict_write;
43 OptKey =:= protocol ->
David Reiss3f660a42010-08-30 22:05:29 +000044 split_options(Rest, [Opt | ProtoIn], TransIn);
45
46split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
47 when OptKey =:= framed;
48 OptKey =:= connect_timeout;
Jens Geyer0b098872015-05-20 21:43:33 +020049 OptKey =:= recv_timeout;
David Robakowskia7d6a972013-08-07 05:51:00 +020050 OptKey =:= sockopts;
51 OptKey =:= ssltransport;
52 OptKey =:= ssloptions->
David Reiss3f660a42010-08-30 22:05:29 +000053 split_options(Rest, ProtoIn, [Opt | TransIn]).
54
55
56%% Client constructor for the common-case of socket transports
David Reiss3f660a42010-08-30 22:05:29 +000057new(Host, Port, Service, Options)
58 when is_integer(Port), is_atom(Service), is_list(Options) ->
David Robakowskia7d6a972013-08-07 05:51:00 +020059 {ProtoOpts, TransOpts0} = split_options(Options),
60
61 {TransportModule, TransOpts2} = case lists:keytake(ssltransport, 1, TransOpts0) of
62 {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
63 false -> {thrift_socket_transport, TransOpts0}
64 end,
David Reiss3f660a42010-08-30 22:05:29 +000065
Nobuaki Sukegawab31f0902015-11-01 17:00:34 +090066 {ProtocolModule, ProtoOpts1} = case lists:keytake(protocol, 1, ProtoOpts) of
67 {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
68 {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
69 {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
70 false -> {thrift_binary_protocol, ProtoOpts}
71 end,
David Reiss3f660a42010-08-30 22:05:29 +000072 {ok, TransportFactory} =
David Robakowskia7d6a972013-08-07 05:51:00 +020073 TransportModule:new_transport_factory(Host, Port, TransOpts2),
David Reiss3f660a42010-08-30 22:05:29 +000074
Nobuaki Sukegawab31f0902015-11-01 17:00:34 +090075 {ok, ProtocolFactory} = ProtocolModule:new_protocol_factory(
76 TransportFactory, ProtoOpts1),
David Reiss3f660a42010-08-30 22:05:29 +000077
Jens Geyera6b328f2014-03-18 23:51:23 +020078 case ProtocolFactory() of
79 {ok, Protocol} ->
80 thrift_client:new(Protocol, Service);
81 {error, Error} ->
82 {error, Error}
83 end.
David Robakowskiae971ce2013-08-02 12:16:00 +020084
85-spec new_multiplexed(Host, Port, Services, Options) -> {ok, ServiceThriftClientList} when
86 Host :: nonempty_string(),
87 Port :: non_neg_integer(),
88 Services :: multiplexed_service_map(),
89 Options :: list(),
90 ServiceThriftClientList :: [{ServiceName::list(), ThriftClient::term()}].
91new_multiplexed(Host, Port, Services, Options) when is_integer(Port),
92 is_list(Services),
93 is_list(Options) ->
94 new_multiplexed(thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options).
95
96-spec new_multiplexed(TransportFactoryTuple, Services, Options) -> {ok, ServiceThriftClientList} when
97 TransportFactoryTuple :: {ok, TransportFactory::term()},
98 Services :: multiplexed_service_map(),
99 Options :: list(),
100 ServiceThriftClientList :: [{ServiceName::service_name(), ThriftClient::term()}].
101new_multiplexed(TransportFactoryTuple, Services, Options) when is_list(Services),
102 is_list(Options),
103 is_tuple(TransportFactoryTuple) ->
104 {ProtoOpts, _} = split_options(Options),
105
106 {ok, TransportFactory} = TransportFactoryTuple,
107
108 {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(TransportFactory, ProtoOpts),
109
110 {ok, Protocol} = ProtocolFactory(),
111
112 {ok, [{ServiceName, element(2, thrift_client:new(element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service))} || {ServiceName, Service} <- Services]}.