blob: 7c5f094beaee9672d411c5e05831da7f94ce0695 [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
Sergei Elin45764092022-09-23 23:21:31 +030025-type service_name() :: nonempty_string().
26-type service_module() :: atom().
27-type multiplexed_service_map() :: [
28 {ServiceName :: service_name(), ServiceModule :: service_module()}
29].
David Reiss3f660a42010-08-30 22:05:29 +000030
31%%
32%% Splits client options into client, protocol, and transport options
33%%
34%% split_options([Options...]) -> {ProtocolOptions, TransportOptions}
35%%
36split_options(Options) ->
37 split_options(Options, [], []).
38
39split_options([], ProtoIn, TransIn) ->
40 {ProtoIn, TransIn};
Sergei Elin45764092022-09-23 23:21:31 +030041split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
42 OptKey =:= strict_read;
43 OptKey =:= strict_write;
44 OptKey =:= protocol
45->
David Reiss3f660a42010-08-30 22:05:29 +000046 split_options(Rest, [Opt | ProtoIn], TransIn);
Sergei Elin45764092022-09-23 23:21:31 +030047split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
48 OptKey =:= framed;
49 OptKey =:= connect_timeout;
50 OptKey =:= recv_timeout;
51 OptKey =:= sockopts;
52 OptKey =:= ssltransport;
53 OptKey =:= ssloptions
54->
David Reiss3f660a42010-08-30 22:05:29 +000055 split_options(Rest, ProtoIn, [Opt | TransIn]).
56
David Reiss3f660a42010-08-30 22:05:29 +000057%% Client constructor for the common-case of socket transports
Sergei Elin45764092022-09-23 23:21:31 +030058new(Host, Port, Service, Options) when
59 is_integer(Port), is_atom(Service), is_list(Options)
60->
David Robakowskia7d6a972013-08-07 05:51:00 +020061 {ProtoOpts, TransOpts0} = split_options(Options),
62
Sergei Elin45764092022-09-23 23:21:31 +030063 {TransportModule, TransOpts2} =
64 case lists:keytake(ssltransport, 1, TransOpts0) of
65 {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
66 false -> {thrift_socket_transport, TransOpts0}
67 end,
David Reiss3f660a42010-08-30 22:05:29 +000068
Sergei Elin45764092022-09-23 23:21:31 +030069 {ProtocolModule, ProtoOpts1} =
70 case lists:keytake(protocol, 1, ProtoOpts) of
71 {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
72 {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
73 {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
74 false -> {thrift_binary_protocol, ProtoOpts}
75 end,
David Reiss3f660a42010-08-30 22:05:29 +000076 {ok, TransportFactory} =
David Robakowskia7d6a972013-08-07 05:51:00 +020077 TransportModule:new_transport_factory(Host, Port, TransOpts2),
David Reiss3f660a42010-08-30 22:05:29 +000078
Nobuaki Sukegawab31f0902015-11-01 17:00:34 +090079 {ok, ProtocolFactory} = ProtocolModule:new_protocol_factory(
Sergei Elin45764092022-09-23 23:21:31 +030080 TransportFactory, ProtoOpts1
81 ),
David Reiss3f660a42010-08-30 22:05:29 +000082
Jens Geyera6b328f2014-03-18 23:51:23 +020083 case ProtocolFactory() of
84 {ok, Protocol} ->
85 thrift_client:new(Protocol, Service);
86 {error, Error} ->
87 {error, Error}
88 end.
David Robakowskiae971ce2013-08-02 12:16:00 +020089
90-spec new_multiplexed(Host, Port, Services, Options) -> {ok, ServiceThriftClientList} when
Sergei Elin45764092022-09-23 23:21:31 +030091 Host :: nonempty_string(),
92 Port :: non_neg_integer(),
93 Services :: multiplexed_service_map(),
94 Options :: list(),
95 ServiceThriftClientList :: [{ServiceName :: list(), ThriftClient :: term()}].
96new_multiplexed(Host, Port, Services, Options) when
97 is_integer(Port),
98 is_list(Services),
99 is_list(Options)
100->
101 new_multiplexed(
102 thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options
103 ).
David Robakowskiae971ce2013-08-02 12:16:00 +0200104
Sergei Elin45764092022-09-23 23:21:31 +0300105-spec new_multiplexed(TransportFactoryTuple, Services, Options) ->
106 {ok, ServiceThriftClientList}
107when
108 TransportFactoryTuple :: {ok, TransportFactory :: term()},
109 Services :: multiplexed_service_map(),
110 Options :: list(),
111 ServiceThriftClientList :: [{ServiceName :: service_name(), ThriftClient :: term()}].
112new_multiplexed(TransportFactoryTuple, Services, Options) when
113 is_list(Services),
114 is_list(Options),
115 is_tuple(TransportFactoryTuple)
116->
David Robakowskiae971ce2013-08-02 12:16:00 +0200117 {ProtoOpts, _} = split_options(Options),
118
119 {ok, TransportFactory} = TransportFactoryTuple,
120
Sergei Elin45764092022-09-23 23:21:31 +0300121 {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
122 TransportFactory, ProtoOpts
123 ),
David Robakowskiae971ce2013-08-02 12:16:00 +0200124
125 {ok, Protocol} = ProtocolFactory(),
126
Sergei Elin45764092022-09-23 23:21:31 +0300127 {ok, [
128 {ServiceName,
129 element(
130 2,
131 thrift_client:new(
132 element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service
133 )
134 )}
135 || {ServiceName, Service} <- Services
136 ]}.