blob: 0819b8ca54ce6a59e431e63d8642d7e3da29109e [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);
134 return 255;
135 }
136 g_option_context_free (option_context);
137
138 /* Validate the parsed options */
139 if (server_type_option != NULL &&
140 strncmp (server_type_option, "simple", 7) != 0) {
141 fprintf (stderr, "Unknown server type %s\n", protocol_option);
142 options_valid = FALSE;
143 }
144
Chandler May6dde90b2016-01-10 06:01:10 +0000145 if (protocol_option != NULL) {
146 if (strncmp (protocol_option, "compact", 8) == 0) {
147 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
148 protocol_name = "compact";
149 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200150 else if (strncmp (protocol_option, "multi", 6) == 0) {
151 protocol_name = "binary:multi";
152 }
153 else if (strncmp (protocol_option, "multic", 7) == 0) {
154 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
155 protocol_name = "compact:multic";
156 }
Chandler May6dde90b2016-01-10 06:01:10 +0000157 else if (strncmp (protocol_option, "binary", 7) != 0) {
158 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
159 options_valid = FALSE;
160 }
Roger Meier15df0762014-09-29 20:50:56 +0200161 }
162
163 if (transport_option != NULL) {
164 if (strncmp (transport_option, "framed", 7) == 0) {
165 transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
166 transport_name = "framed";
167 }
168 else if (strncmp (transport_option, "buffered", 9) != 0) {
169 fprintf (stderr, "Unknown transport type %s\n", transport_option);
170 options_valid = FALSE;
171 }
172 }
173
174 if (!options_valid)
175 return 254;
176
177 /* Establish all our connection objects */
178 handler = g_object_new (TYPE_THRIFT_TEST_HANDLER,
179 NULL);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200180
181
182
183 if(strstr(protocol_name, ":multi")){
184 /* When a multiplexed processor is involved the handler is not
185 registered as usual. We create the processor and the real
186 processor is registered. Multiple processors can be registered
187 at once. This is why we don't have a constructor property */
188 processor = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROCESSOR,
189 NULL);
190
191 handler_second_service = g_object_new (TYPE_SECOND_SERVICE_HANDLER,
192 NULL);
193
194 processor_test = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
195 "handler", handler,
196 NULL);
197 processor_second_service = g_object_new (T_TEST_TYPE_SECOND_SERVICE_PROCESSOR,
198 "handler", handler_second_service,
199 NULL);
200
201 /* We register a test processor with Multiplexed name ThriftTest */
202 if(!thrift_multiplexed_processor_register_processor(processor,
203 "ThriftTest", processor_test,
204 &error)){
205 g_message ("thrift_server_serve: %s",
206 error != NULL ? error->message : "(null)");
207 g_clear_error (&error);
208 }
209 /* We register a second test processor with Multiplexed name SecondService
210 * we are responsible of freeing the processor when it's not used anymore */
211 if(!thrift_multiplexed_processor_register_processor(processor,
212 "SecondService", processor_second_service,
213 &error)){
214 g_message ("thrift_server_serve: %s",
215 error != NULL ? error->message : "(null)");
216 g_clear_error (&error);
217 }
218
219 }else{
220 processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
221 "handler", handler,
222 NULL);
223 }
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700224 if (path_option) {
225 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
226 "path", path_option,
227 NULL);
228 } else {
229 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
230 "port", port,
231 NULL);
232 }
Roger Meier15df0762014-09-29 20:50:56 +0200233 transport_factory = g_object_new (transport_factory_type,
234 NULL);
Chandler May6dde90b2016-01-10 06:01:10 +0000235
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200236 if (strstr (protocol_name, "compact") != NULL) {
Chandler May6dde90b2016-01-10 06:01:10 +0000237 protocol_factory = g_object_new (protocol_factory_type,
238 "string_limit", string_limit,
239 "container_limit", container_limit,
240 NULL);
241 } else {
242 protocol_factory = g_object_new (protocol_factory_type,
243 NULL);
244 }
Roger Meier15df0762014-09-29 20:50:56 +0200245
246 server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
247 "processor", processor,
248 "server_transport", server_transport,
249 "input_transport_factory", transport_factory,
250 "output_transport_factory", transport_factory,
251 "input_protocol_factory", protocol_factory,
252 "output_protocol_factory", protocol_factory,
253 NULL);
254
255 /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
256 the server gracefully */
257 memset (&sigint_action, 0, sizeof (sigint_action));
258 sigint_action.sa_handler = sigint_handler;
259 sigint_action.sa_flags = SA_RESETHAND;
260 sigaction (SIGINT, &sigint_action, NULL);
261
Kevin Wojniak6c847d22019-07-01 17:11:56 -0700262 if (path_option) {
263 printf ("Starting \"%s\" server (%s/%s) listen on: %s\n",
264 server_name,
265 transport_name,
266 protocol_name,
267 path_option);
268 } else {
269 printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
270 server_name,
271 transport_name,
272 protocol_name,
273 port);
274 }
Roger Meier15df0762014-09-29 20:50:56 +0200275 fflush (stdout);
276
277 /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
278 thrift_server_serve (server, &error);
279
280 /* If the server stopped for any reason other than being interrupted by the
281 user, report the error */
282 if (!sigint_received) {
283 g_message ("thrift_server_serve: %s",
284 error != NULL ? error->message : "(null)");
285 g_clear_error (&error);
286 }
287
288 puts ("done.");
289
290 g_object_unref (server);
291 g_object_unref (protocol_factory);
292 g_object_unref (transport_factory);
293 g_object_unref (server_transport);
294 g_object_unref (processor);
295 g_object_unref (handler);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200296 if(handler_second_service){
297 g_object_unref (handler_second_service);
298 }
299 if(processor_test){
300 g_object_unref (processor_test);
301 }
302 if(processor_second_service){
303 g_object_unref (processor_second_service);
304 }
Roger Meier15df0762014-09-29 20:50:56 +0200305
306 return 0;
307}