blob: c949530de014b02b7c1dc799216f80951ccc0aa3 [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>
35#include <thrift/c_glib/transport/thrift_server_socket.h>
36#include <thrift/c_glib/transport/thrift_server_transport.h>
37#include <thrift/c_glib/transport/thrift_transport.h>
38#include <thrift/c_glib/transport/thrift_transport_factory.h>
39
40#include "../gen-c_glib/t_test_thrift_test.h"
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020041#include "../gen-c_glib/t_test_second_service.h"
Roger Meier15df0762014-09-29 20:50:56 +020042
43#include "thrift_test_handler.h"
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020044#include "thrift_second_service_handler.h"
Roger Meier15df0762014-09-29 20:50:56 +020045
46/* Our server object, declared globally so it is accessible within the SIGINT
47 signal handler */
48ThriftServer *server = NULL;
49
50/* A flag that indicates whether the server was interrupted with SIGINT
51 (i.e. Ctrl-C) so we can tell whether its termination was abnormal */
52gboolean sigint_received = FALSE;
53
54/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the server */
55static void
56sigint_handler (int signal_number)
57{
58 THRIFT_UNUSED_VAR (signal_number);
59
60 /* Take note we were called */
61 sigint_received = TRUE;
62
63 /* Shut down the server gracefully */
64 if (server != NULL)
65 thrift_server_stop (server);
66}
67
68int
69main (int argc, char **argv)
70{
71 static gint port = 9090;
Kevin Wojniak6c847d22019-07-01 17:11:56 -070072 static gchar *path_option = NULL;
Roger Meier15df0762014-09-29 20:50:56 +020073 static gchar *server_type_option = NULL;
74 static gchar *transport_option = NULL;
75 static gchar *protocol_option = NULL;
Chandler May6dde90b2016-01-10 06:01:10 +000076 static gint string_limit = 0;
77 static gint container_limit = 0;
Roger Meier15df0762014-09-29 20:50:56 +020078
79 static
80 GOptionEntry option_entries[] = {
81 { "port", 0, 0, G_OPTION_ARG_INT, &port,
82 "Port number to connect (=9090)", NULL },
Kevin Wojniak6c847d22019-07-01 17:11:56 -070083 { "domain-socket", 0, 0, G_OPTION_ARG_STRING, &path_option,
84 "Unix socket domain path to connect", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020085 { "server-type", 0, 0, G_OPTION_ARG_STRING, &server_type_option,
86 "Type of server: simple (=simple)", NULL },
87 { "transport", 0, 0, G_OPTION_ARG_STRING, &transport_option,
88 "Transport: buffered, framed (=buffered)", NULL },
89 { "protocol", 0, 0, G_OPTION_ARG_STRING, &protocol_option,
Chandler May6dde90b2016-01-10 06:01:10 +000090 "Protocol: binary, compact (=binary)", NULL },
91 { "string-limit", 0, 0, G_OPTION_ARG_INT, &string_limit,
92 "Max string length (=none)", NULL },
93 { "container-limit", 0, 0, G_OPTION_ARG_INT, &container_limit,
94 "Max container length (=none)", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020095 { NULL }
96 };
97
98 gchar *server_name = "simple";
99 gchar *transport_name = "buffered";
100 GType transport_factory_type = THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY;
101 gchar *protocol_name = "binary";
102 GType protocol_factory_type = THRIFT_TYPE_BINARY_PROTOCOL_FACTORY;
103
104 TTestThriftTestHandler *handler;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200105 TTestThriftTestHandler *handler_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200106 ThriftProcessor *processor;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200107 ThriftProcessor *processor_test = NULL;
108 ThriftProcessor *processor_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200109 ThriftServerTransport *server_transport;
110 ThriftTransportFactory *transport_factory;
111 ThriftProtocolFactory *protocol_factory;
112
113 struct sigaction sigint_action;
114
115 GOptionContext *option_context;
116 gboolean options_valid = TRUE;
117
118 GError *error = NULL;
119
120#if (!GLIB_CHECK_VERSION (2, 36, 0))
121 g_type_init ();
122#endif
123
124 /* Configure and parse our command-line options */
125 option_context = g_option_context_new (NULL);
126 g_option_context_add_main_entries (option_context,
127 option_entries,
128 NULL);
129 if (g_option_context_parse (option_context,
130 &argc,
131 &argv,
132 &error) == FALSE) {
133 fprintf (stderr, "%s\n", error->message);
wangyunjian5f352752020-03-29 10:56:20 +0800134 g_clear_error (&error);
135 g_option_context_free (option_context);
Roger Meier15df0762014-09-29 20:50:56 +0200136 return 255;
137 }
138 g_option_context_free (option_context);
139
140 /* Validate the parsed options */
141 if (server_type_option != NULL &&
142 strncmp (server_type_option, "simple", 7) != 0) {
143 fprintf (stderr, "Unknown server type %s\n", protocol_option);
144 options_valid = FALSE;
145 }
146
Chandler May6dde90b2016-01-10 06:01:10 +0000147 if (protocol_option != NULL) {
148 if (strncmp (protocol_option, "compact", 8) == 0) {
149 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
150 protocol_name = "compact";
151 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200152 else if (strncmp (protocol_option, "multi", 6) == 0) {
153 protocol_name = "binary:multi";
154 }
155 else if (strncmp (protocol_option, "multic", 7) == 0) {
156 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
157 protocol_name = "compact:multic";
158 }
Chandler May6dde90b2016-01-10 06:01:10 +0000159 else if (strncmp (protocol_option, "binary", 7) != 0) {
160 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
161 options_valid = FALSE;
162 }
Roger Meier15df0762014-09-29 20:50:56 +0200163 }
164
165 if (transport_option != NULL) {
166 if (strncmp (transport_option, "framed", 7) == 0) {
167 transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
168 transport_name = "framed";
169 }
170 else if (strncmp (transport_option, "buffered", 9) != 0) {
171 fprintf (stderr, "Unknown transport type %s\n", transport_option);
172 options_valid = FALSE;
173 }
174 }
175
176 if (!options_valid)
177 return 254;
178
179 /* Establish all our connection objects */
180 handler = g_object_new (TYPE_THRIFT_TEST_HANDLER,
181 NULL);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200182
183
184
185 if(strstr(protocol_name, ":multi")){
186 /* When a multiplexed processor is involved the handler is not
187 registered as usual. We create the processor and the real
188 processor is registered. Multiple processors can be registered
189 at once. This is why we don't have a constructor property */
190 processor = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROCESSOR,
191 NULL);
192
193 handler_second_service = g_object_new (TYPE_SECOND_SERVICE_HANDLER,
194 NULL);
195
196 processor_test = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
197 "handler", handler,
198 NULL);
199 processor_second_service = g_object_new (T_TEST_TYPE_SECOND_SERVICE_PROCESSOR,
200 "handler", handler_second_service,
201 NULL);
202
203 /* We register a test processor with Multiplexed name ThriftTest */
204 if(!thrift_multiplexed_processor_register_processor(processor,
205 "ThriftTest", processor_test,
206 &error)){
207 g_message ("thrift_server_serve: %s",
208 error != NULL ? error->message : "(null)");
209 g_clear_error (&error);
210 }
211 /* We register a second test processor with Multiplexed name SecondService
212 * we are responsible of freeing the processor when it's not used anymore */
213 if(!thrift_multiplexed_processor_register_processor(processor,
214 "SecondService", processor_second_service,
215 &error)){
216 g_message ("thrift_server_serve: %s",
217 error != NULL ? error->message : "(null)");
218 g_clear_error (&error);
219 }
220
221 }else{
222 processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
223 "handler", handler,
224 NULL);
225 }
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700226 if (path_option) {
227 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
228 "path", path_option,
229 NULL);
230 } else {
231 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
232 "port", port,
233 NULL);
234 }
Roger Meier15df0762014-09-29 20:50:56 +0200235 transport_factory = g_object_new (transport_factory_type,
236 NULL);
Chandler May6dde90b2016-01-10 06:01:10 +0000237
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200238 if (strstr (protocol_name, "compact") != NULL) {
Chandler May6dde90b2016-01-10 06:01:10 +0000239 protocol_factory = g_object_new (protocol_factory_type,
240 "string_limit", string_limit,
241 "container_limit", container_limit,
242 NULL);
243 } else {
244 protocol_factory = g_object_new (protocol_factory_type,
245 NULL);
246 }
Roger Meier15df0762014-09-29 20:50:56 +0200247
248 server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
249 "processor", processor,
250 "server_transport", server_transport,
251 "input_transport_factory", transport_factory,
252 "output_transport_factory", transport_factory,
253 "input_protocol_factory", protocol_factory,
254 "output_protocol_factory", protocol_factory,
255 NULL);
256
257 /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
258 the server gracefully */
259 memset (&sigint_action, 0, sizeof (sigint_action));
260 sigint_action.sa_handler = sigint_handler;
261 sigint_action.sa_flags = SA_RESETHAND;
262 sigaction (SIGINT, &sigint_action, NULL);
263
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700264 if (path_option) {
265 printf ("Starting \"%s\" server (%s/%s) listen on: %s\n",
266 server_name,
267 transport_name,
268 protocol_name,
269 path_option);
270 } else {
271 printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
272 server_name,
273 transport_name,
274 protocol_name,
275 port);
276 }
Roger Meier15df0762014-09-29 20:50:56 +0200277 fflush (stdout);
278
279 /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
280 thrift_server_serve (server, &error);
281
282 /* If the server stopped for any reason other than being interrupted by the
283 user, report the error */
284 if (!sigint_received) {
285 g_message ("thrift_server_serve: %s",
286 error != NULL ? error->message : "(null)");
Roger Meier15df0762014-09-29 20:50:56 +0200287 }
288
289 puts ("done.");
290
wangyunjian5f352752020-03-29 10:56:20 +0800291 g_clear_error (&error);
Roger Meier15df0762014-09-29 20:50:56 +0200292 g_object_unref (server);
293 g_object_unref (protocol_factory);
294 g_object_unref (transport_factory);
295 g_object_unref (server_transport);
296 g_object_unref (processor);
297 g_object_unref (handler);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200298 if(handler_second_service){
299 g_object_unref (handler_second_service);
300 }
301 if(processor_test){
302 g_object_unref (processor_test);
303 }
304 if(processor_second_service){
305 g_object_unref (processor_second_service);
306 }
Roger Meier15df0762014-09-29 20:50:56 +0200307
308 return 0;
309}