blob: c57e1cfb9c3e07d54d99c18ba69bbb27ff0508d5 [file] [log] [blame]
Roger Meier15df0762014-09-29 20:50:56 +02001/*
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#include <glib-object.h>
21#include <signal.h>
22#include <stdio.h>
23#include <string.h>
24
25#include <thrift/c_glib/thrift.h>
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020026#include <thrift/c_glib/processor/thrift_multiplexed_processor.h>
Roger Meier15df0762014-09-29 20:50:56 +020027#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
Chandler May6dde90b2016-01-10 06:01:10 +000028#include <thrift/c_glib/protocol/thrift_compact_protocol_factory.h>
Roger Meier15df0762014-09-29 20:50:56 +020029#include <thrift/c_glib/server/thrift_server.h>
30#include <thrift/c_glib/server/thrift_simple_server.h>
31#include <thrift/c_glib/transport/thrift_buffered_transport.h>
32#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
33#include <thrift/c_glib/transport/thrift_framed_transport.h>
34#include <thrift/c_glib/transport/thrift_framed_transport_factory.h>
zeshuai007037753e2020-11-30 11:16:10 +080035#include <thrift/c_glib/transport/thrift_zlib_transport.h>
36#include <thrift/c_glib/transport/thrift_zlib_transport_factory.h>
Roger Meier15df0762014-09-29 20:50:56 +020037#include <thrift/c_glib/transport/thrift_server_socket.h>
38#include <thrift/c_glib/transport/thrift_server_transport.h>
39#include <thrift/c_glib/transport/thrift_transport.h>
40#include <thrift/c_glib/transport/thrift_transport_factory.h>
41
42#include "../gen-c_glib/t_test_thrift_test.h"
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020043#include "../gen-c_glib/t_test_second_service.h"
Roger Meier15df0762014-09-29 20:50:56 +020044
45#include "thrift_test_handler.h"
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020046#include "thrift_second_service_handler.h"
Roger Meier15df0762014-09-29 20:50:56 +020047
48/* Our server object, declared globally so it is accessible within the SIGINT
49 signal handler */
50ThriftServer *server = NULL;
51
52/* A flag that indicates whether the server was interrupted with SIGINT
53 (i.e. Ctrl-C) so we can tell whether its termination was abnormal */
54gboolean sigint_received = FALSE;
55
56/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the server */
57static void
58sigint_handler (int signal_number)
59{
60 THRIFT_UNUSED_VAR (signal_number);
61
62 /* Take note we were called */
63 sigint_received = TRUE;
64
65 /* Shut down the server gracefully */
66 if (server != NULL)
67 thrift_server_stop (server);
68}
69
70int
71main (int argc, char **argv)
72{
73 static gint port = 9090;
Kevin Wojniak6c847d22019-07-01 17:11:56 -070074 static gchar *path_option = NULL;
Roger Meier15df0762014-09-29 20:50:56 +020075 static gchar *server_type_option = NULL;
76 static gchar *transport_option = NULL;
77 static gchar *protocol_option = NULL;
Chandler May6dde90b2016-01-10 06:01:10 +000078 static gint string_limit = 0;
79 static gint container_limit = 0;
Roger Meier15df0762014-09-29 20:50:56 +020080
81 static
82 GOptionEntry option_entries[] = {
83 { "port", 0, 0, G_OPTION_ARG_INT, &port,
84 "Port number to connect (=9090)", NULL },
Kevin Wojniak6c847d22019-07-01 17:11:56 -070085 { "domain-socket", 0, 0, G_OPTION_ARG_STRING, &path_option,
86 "Unix socket domain path to connect", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020087 { "server-type", 0, 0, G_OPTION_ARG_STRING, &server_type_option,
88 "Type of server: simple (=simple)", NULL },
89 { "transport", 0, 0, G_OPTION_ARG_STRING, &transport_option,
zeshuai007037753e2020-11-30 11:16:10 +080090 "Transport: buffered, framed, zlib (=buffered)", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020091 { "protocol", 0, 0, G_OPTION_ARG_STRING, &protocol_option,
Chandler May6dde90b2016-01-10 06:01:10 +000092 "Protocol: binary, compact (=binary)", NULL },
93 { "string-limit", 0, 0, G_OPTION_ARG_INT, &string_limit,
94 "Max string length (=none)", NULL },
95 { "container-limit", 0, 0, G_OPTION_ARG_INT, &container_limit,
96 "Max container length (=none)", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020097 { NULL }
98 };
99
100 gchar *server_name = "simple";
101 gchar *transport_name = "buffered";
102 GType transport_factory_type = THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY;
103 gchar *protocol_name = "binary";
104 GType protocol_factory_type = THRIFT_TYPE_BINARY_PROTOCOL_FACTORY;
105
106 TTestThriftTestHandler *handler;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200107 TTestThriftTestHandler *handler_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200108 ThriftProcessor *processor;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200109 ThriftProcessor *processor_test = NULL;
110 ThriftProcessor *processor_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200111 ThriftServerTransport *server_transport;
112 ThriftTransportFactory *transport_factory;
113 ThriftProtocolFactory *protocol_factory;
114
115 struct sigaction sigint_action;
116
117 GOptionContext *option_context;
118 gboolean options_valid = TRUE;
119
120 GError *error = NULL;
121
122#if (!GLIB_CHECK_VERSION (2, 36, 0))
123 g_type_init ();
124#endif
125
126 /* Configure and parse our command-line options */
127 option_context = g_option_context_new (NULL);
128 g_option_context_add_main_entries (option_context,
129 option_entries,
130 NULL);
131 if (g_option_context_parse (option_context,
132 &argc,
133 &argv,
134 &error) == FALSE) {
135 fprintf (stderr, "%s\n", error->message);
wangyunjian5f352752020-03-29 10:56:20 +0800136 g_clear_error (&error);
137 g_option_context_free (option_context);
Roger Meier15df0762014-09-29 20:50:56 +0200138 return 255;
139 }
140 g_option_context_free (option_context);
141
142 /* Validate the parsed options */
143 if (server_type_option != NULL &&
144 strncmp (server_type_option, "simple", 7) != 0) {
145 fprintf (stderr, "Unknown server type %s\n", protocol_option);
146 options_valid = FALSE;
147 }
148
Chandler May6dde90b2016-01-10 06:01:10 +0000149 if (protocol_option != NULL) {
150 if (strncmp (protocol_option, "compact", 8) == 0) {
151 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
152 protocol_name = "compact";
153 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200154 else if (strncmp (protocol_option, "multi", 6) == 0) {
155 protocol_name = "binary:multi";
156 }
157 else if (strncmp (protocol_option, "multic", 7) == 0) {
158 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
159 protocol_name = "compact:multic";
160 }
Chandler May6dde90b2016-01-10 06:01:10 +0000161 else if (strncmp (protocol_option, "binary", 7) != 0) {
162 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
163 options_valid = FALSE;
164 }
Roger Meier15df0762014-09-29 20:50:56 +0200165 }
166
167 if (transport_option != NULL) {
168 if (strncmp (transport_option, "framed", 7) == 0) {
169 transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
170 transport_name = "framed";
171 }
zeshuai007037753e2020-11-30 11:16:10 +0800172 else if (strncmp (transport_option, "zlib", 5) == 0) {
173 transport_factory_type = THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY;
174 transport_name = "zlib";
175 }
Roger Meier15df0762014-09-29 20:50:56 +0200176 else if (strncmp (transport_option, "buffered", 9) != 0) {
177 fprintf (stderr, "Unknown transport type %s\n", transport_option);
178 options_valid = FALSE;
179 }
180 }
181
182 if (!options_valid)
183 return 254;
184
185 /* Establish all our connection objects */
186 handler = g_object_new (TYPE_THRIFT_TEST_HANDLER,
187 NULL);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200188
189
190
191 if(strstr(protocol_name, ":multi")){
192 /* When a multiplexed processor is involved the handler is not
193 registered as usual. We create the processor and the real
194 processor is registered. Multiple processors can be registered
195 at once. This is why we don't have a constructor property */
196 processor = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROCESSOR,
197 NULL);
198
199 handler_second_service = g_object_new (TYPE_SECOND_SERVICE_HANDLER,
200 NULL);
201
202 processor_test = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
203 "handler", handler,
204 NULL);
205 processor_second_service = g_object_new (T_TEST_TYPE_SECOND_SERVICE_PROCESSOR,
206 "handler", handler_second_service,
207 NULL);
208
209 /* We register a test processor with Multiplexed name ThriftTest */
210 if(!thrift_multiplexed_processor_register_processor(processor,
211 "ThriftTest", processor_test,
212 &error)){
213 g_message ("thrift_server_serve: %s",
214 error != NULL ? error->message : "(null)");
215 g_clear_error (&error);
216 }
217 /* We register a second test processor with Multiplexed name SecondService
218 * we are responsible of freeing the processor when it's not used anymore */
219 if(!thrift_multiplexed_processor_register_processor(processor,
220 "SecondService", processor_second_service,
221 &error)){
222 g_message ("thrift_server_serve: %s",
223 error != NULL ? error->message : "(null)");
224 g_clear_error (&error);
225 }
226
227 }else{
228 processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
229 "handler", handler,
230 NULL);
231 }
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700232 if (path_option) {
233 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
234 "path", path_option,
235 NULL);
236 } else {
237 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
238 "port", port,
239 NULL);
240 }
Roger Meier15df0762014-09-29 20:50:56 +0200241 transport_factory = g_object_new (transport_factory_type,
242 NULL);
Chandler May6dde90b2016-01-10 06:01:10 +0000243
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200244 if (strstr (protocol_name, "compact") != NULL) {
Chandler May6dde90b2016-01-10 06:01:10 +0000245 protocol_factory = g_object_new (protocol_factory_type,
246 "string_limit", string_limit,
247 "container_limit", container_limit,
248 NULL);
249 } else {
250 protocol_factory = g_object_new (protocol_factory_type,
251 NULL);
252 }
Roger Meier15df0762014-09-29 20:50:56 +0200253
254 server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
255 "processor", processor,
256 "server_transport", server_transport,
257 "input_transport_factory", transport_factory,
258 "output_transport_factory", transport_factory,
259 "input_protocol_factory", protocol_factory,
260 "output_protocol_factory", protocol_factory,
261 NULL);
262
263 /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
264 the server gracefully */
265 memset (&sigint_action, 0, sizeof (sigint_action));
266 sigint_action.sa_handler = sigint_handler;
267 sigint_action.sa_flags = SA_RESETHAND;
268 sigaction (SIGINT, &sigint_action, NULL);
269
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700270 if (path_option) {
271 printf ("Starting \"%s\" server (%s/%s) listen on: %s\n",
272 server_name,
273 transport_name,
274 protocol_name,
275 path_option);
276 } else {
277 printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
278 server_name,
279 transport_name,
280 protocol_name,
281 port);
282 }
Roger Meier15df0762014-09-29 20:50:56 +0200283 fflush (stdout);
284
285 /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
286 thrift_server_serve (server, &error);
287
288 /* If the server stopped for any reason other than being interrupted by the
289 user, report the error */
290 if (!sigint_received) {
291 g_message ("thrift_server_serve: %s",
292 error != NULL ? error->message : "(null)");
Roger Meier15df0762014-09-29 20:50:56 +0200293 }
294
295 puts ("done.");
296
wangyunjian5f352752020-03-29 10:56:20 +0800297 g_clear_error (&error);
Roger Meier15df0762014-09-29 20:50:56 +0200298 g_object_unref (server);
299 g_object_unref (protocol_factory);
300 g_object_unref (transport_factory);
301 g_object_unref (server_transport);
302 g_object_unref (processor);
303 g_object_unref (handler);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200304 if(handler_second_service){
305 g_object_unref (handler_second_service);
306 }
307 if(processor_test){
308 g_object_unref (processor_test);
309 }
310 if(processor_second_service){
311 g_object_unref (processor_second_service);
312 }
Roger Meier15df0762014-09-29 20:50:56 +0200313
314 return 0;
315}