blob: 2d716ec2e6fefdfffa52a3c8bc18abc49d4a921c [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;
72 static gchar *server_type_option = NULL;
73 static gchar *transport_option = NULL;
74 static gchar *protocol_option = NULL;
Chandler May6dde90b2016-01-10 06:01:10 +000075 static gint string_limit = 0;
76 static gint container_limit = 0;
Roger Meier15df0762014-09-29 20:50:56 +020077
78 static
79 GOptionEntry option_entries[] = {
80 { "port", 0, 0, G_OPTION_ARG_INT, &port,
81 "Port number to connect (=9090)", NULL },
82 { "server-type", 0, 0, G_OPTION_ARG_STRING, &server_type_option,
83 "Type of server: simple (=simple)", NULL },
84 { "transport", 0, 0, G_OPTION_ARG_STRING, &transport_option,
85 "Transport: buffered, framed (=buffered)", NULL },
86 { "protocol", 0, 0, G_OPTION_ARG_STRING, &protocol_option,
Chandler May6dde90b2016-01-10 06:01:10 +000087 "Protocol: binary, compact (=binary)", NULL },
88 { "string-limit", 0, 0, G_OPTION_ARG_INT, &string_limit,
89 "Max string length (=none)", NULL },
90 { "container-limit", 0, 0, G_OPTION_ARG_INT, &container_limit,
91 "Max container length (=none)", NULL },
Roger Meier15df0762014-09-29 20:50:56 +020092 { NULL }
93 };
94
95 gchar *server_name = "simple";
96 gchar *transport_name = "buffered";
97 GType transport_factory_type = THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY;
98 gchar *protocol_name = "binary";
99 GType protocol_factory_type = THRIFT_TYPE_BINARY_PROTOCOL_FACTORY;
100
101 TTestThriftTestHandler *handler;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200102 TTestThriftTestHandler *handler_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200103 ThriftProcessor *processor;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200104 ThriftProcessor *processor_test = NULL;
105 ThriftProcessor *processor_second_service = NULL;
Roger Meier15df0762014-09-29 20:50:56 +0200106 ThriftServerTransport *server_transport;
107 ThriftTransportFactory *transport_factory;
108 ThriftProtocolFactory *protocol_factory;
109
110 struct sigaction sigint_action;
111
112 GOptionContext *option_context;
113 gboolean options_valid = TRUE;
114
115 GError *error = NULL;
116
117#if (!GLIB_CHECK_VERSION (2, 36, 0))
118 g_type_init ();
119#endif
120
121 /* Configure and parse our command-line options */
122 option_context = g_option_context_new (NULL);
123 g_option_context_add_main_entries (option_context,
124 option_entries,
125 NULL);
126 if (g_option_context_parse (option_context,
127 &argc,
128 &argv,
129 &error) == FALSE) {
130 fprintf (stderr, "%s\n", error->message);
131 return 255;
132 }
133 g_option_context_free (option_context);
134
135 /* Validate the parsed options */
136 if (server_type_option != NULL &&
137 strncmp (server_type_option, "simple", 7) != 0) {
138 fprintf (stderr, "Unknown server type %s\n", protocol_option);
139 options_valid = FALSE;
140 }
141
Chandler May6dde90b2016-01-10 06:01:10 +0000142 if (protocol_option != NULL) {
143 if (strncmp (protocol_option, "compact", 8) == 0) {
144 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
145 protocol_name = "compact";
146 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200147 else if (strncmp (protocol_option, "multi", 6) == 0) {
148 protocol_name = "binary:multi";
149 }
150 else if (strncmp (protocol_option, "multic", 7) == 0) {
151 protocol_factory_type = THRIFT_TYPE_COMPACT_PROTOCOL_FACTORY;
152 protocol_name = "compact:multic";
153 }
Chandler May6dde90b2016-01-10 06:01:10 +0000154 else if (strncmp (protocol_option, "binary", 7) != 0) {
155 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
156 options_valid = FALSE;
157 }
Roger Meier15df0762014-09-29 20:50:56 +0200158 }
159
160 if (transport_option != NULL) {
161 if (strncmp (transport_option, "framed", 7) == 0) {
162 transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
163 transport_name = "framed";
164 }
165 else if (strncmp (transport_option, "buffered", 9) != 0) {
166 fprintf (stderr, "Unknown transport type %s\n", transport_option);
167 options_valid = FALSE;
168 }
169 }
170
171 if (!options_valid)
172 return 254;
173
174 /* Establish all our connection objects */
175 handler = g_object_new (TYPE_THRIFT_TEST_HANDLER,
176 NULL);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200177
178
179
180 if(strstr(protocol_name, ":multi")){
181 /* When a multiplexed processor is involved the handler is not
182 registered as usual. We create the processor and the real
183 processor is registered. Multiple processors can be registered
184 at once. This is why we don't have a constructor property */
185 processor = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROCESSOR,
186 NULL);
187
188 handler_second_service = g_object_new (TYPE_SECOND_SERVICE_HANDLER,
189 NULL);
190
191 processor_test = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
192 "handler", handler,
193 NULL);
194 processor_second_service = g_object_new (T_TEST_TYPE_SECOND_SERVICE_PROCESSOR,
195 "handler", handler_second_service,
196 NULL);
197
198 /* We register a test processor with Multiplexed name ThriftTest */
199 if(!thrift_multiplexed_processor_register_processor(processor,
200 "ThriftTest", processor_test,
201 &error)){
202 g_message ("thrift_server_serve: %s",
203 error != NULL ? error->message : "(null)");
204 g_clear_error (&error);
205 }
206 /* We register a second test processor with Multiplexed name SecondService
207 * we are responsible of freeing the processor when it's not used anymore */
208 if(!thrift_multiplexed_processor_register_processor(processor,
209 "SecondService", processor_second_service,
210 &error)){
211 g_message ("thrift_server_serve: %s",
212 error != NULL ? error->message : "(null)");
213 g_clear_error (&error);
214 }
215
216 }else{
217 processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
218 "handler", handler,
219 NULL);
220 }
Roger Meier15df0762014-09-29 20:50:56 +0200221 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
222 "port", port,
223 NULL);
224 transport_factory = g_object_new (transport_factory_type,
225 NULL);
Chandler May6dde90b2016-01-10 06:01:10 +0000226
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200227 if (strstr (protocol_name, "compact") != NULL) {
Chandler May6dde90b2016-01-10 06:01:10 +0000228 protocol_factory = g_object_new (protocol_factory_type,
229 "string_limit", string_limit,
230 "container_limit", container_limit,
231 NULL);
232 } else {
233 protocol_factory = g_object_new (protocol_factory_type,
234 NULL);
235 }
Roger Meier15df0762014-09-29 20:50:56 +0200236
237 server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
238 "processor", processor,
239 "server_transport", server_transport,
240 "input_transport_factory", transport_factory,
241 "output_transport_factory", transport_factory,
242 "input_protocol_factory", protocol_factory,
243 "output_protocol_factory", protocol_factory,
244 NULL);
245
246 /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
247 the server gracefully */
248 memset (&sigint_action, 0, sizeof (sigint_action));
249 sigint_action.sa_handler = sigint_handler;
250 sigint_action.sa_flags = SA_RESETHAND;
251 sigaction (SIGINT, &sigint_action, NULL);
252
253 printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
254 server_name,
255 transport_name,
256 protocol_name,
257 port);
258 fflush (stdout);
259
260 /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
261 thrift_server_serve (server, &error);
262
263 /* If the server stopped for any reason other than being interrupted by the
264 user, report the error */
265 if (!sigint_received) {
266 g_message ("thrift_server_serve: %s",
267 error != NULL ? error->message : "(null)");
268 g_clear_error (&error);
269 }
270
271 puts ("done.");
272
273 g_object_unref (server);
274 g_object_unref (protocol_factory);
275 g_object_unref (transport_factory);
276 g_object_unref (server_transport);
277 g_object_unref (processor);
278 g_object_unref (handler);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200279 if(handler_second_service){
280 g_object_unref (handler_second_service);
281 }
282 if(processor_test){
283 g_object_unref (processor_test);
284 }
285 if(processor_second_service){
286 g_object_unref (processor_second_service);
287 }
Roger Meier15df0762014-09-29 20:50:56 +0200288
289 return 0;
290}