Repository: thrift Updated Branches: refs/heads/master 06190874c -> bc0082e02
THRIFT-3706: Implement multiplexed protocol client and test client for c_glib; test server for java; integrate into crosstest Client: c_glib This closes #1191 This closes #1199 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/bc0082e0 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/bc0082e0 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/bc0082e0 Branch: refs/heads/master Commit: bc0082e02357de2f30b997188bdfa94d703331f4 Parents: 0619087 Author: Gonzalo Aguilar Delgado <gagui...@level2crm.com> Authored: Fri Mar 4 13:16:22 2016 +0100 Committer: James E. King, III <jk...@apache.org> Committed: Mon Feb 20 14:04:17 2017 -0500 ---------------------------------------------------------------------- lib/c_glib/Makefile.am | 6 +- .../protocol/thrift_multiplexed_protocol.c | 187 ++++++ .../protocol/thrift_multiplexed_protocol.h | 77 +++ .../c_glib/protocol/thrift_protocol_decorator.c | 651 +++++++++++++++++++ .../c_glib/protocol/thrift_protocol_decorator.h | 77 +++ .../test/org/apache/thrift/test/TestServer.java | 62 +- test/c_glib/src/test_client.c | 57 +- test/crossrunner/report.py | 8 +- test/tests.json | 10 +- 9 files changed, 1103 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/Makefile.am ---------------------------------------------------------------------- diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am index b66c89b..8e7bf88 100755 --- a/lib/c_glib/Makefile.am +++ b/lib/c_glib/Makefile.am @@ -35,8 +35,10 @@ libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \ src/thrift/c_glib/processor/thrift_processor.c \ src/thrift/c_glib/processor/thrift_dispatch_processor.c \ src/thrift/c_glib/protocol/thrift_protocol.c \ + src/thrift/c_glib/protocol/thrift_protocol_decorator.c \ src/thrift/c_glib/protocol/thrift_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_binary_protocol.c \ + src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \ src/thrift/c_glib/protocol/thrift_compact_protocol.c \ src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c \ @@ -67,11 +69,13 @@ include_thrift_HEADERS = \ include_protocoldir = $(include_thriftdir)/protocol include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \ + src/thrift/c_glib/protocol/thrift_protocol_decorator.h \ src/thrift/c_glib/protocol/thrift_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_binary_protocol.h \ src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \ src/thrift/c_glib/protocol/thrift_compact_protocol.h \ - src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h + src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h \ + src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h include_transportdir = $(include_thriftdir)/transport include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \ http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c ---------------------------------------------------------------------- diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c new file mode 100644 index 0000000..86f8097 --- /dev/null +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string.h> +#include <stdio.h> +#include <glib.h> +#include <glib-object.h> + +#include <thrift/c_glib/thrift.h> +#include <thrift/c_glib/protocol/thrift_protocol.h> +#include <thrift/c_glib/protocol/thrift_protocol_decorator.h> +#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h> + + +enum +{ + PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME = 1, + PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR, + PROP_THRIFT_MULTIPLEXED_PROTOCOL_END +}; + +G_DEFINE_TYPE(ThriftMultiplexedProtocol, thrift_multiplexed_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR) + + +static GParamSpec *thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_END] = { NULL, }; + +gint32 +thrift_multiplexed_protocol_write_message_begin (ThriftMultiplexedProtocol *protocol, + const gchar *name, const ThriftMessageType message_type, + const gint32 seqid, GError **error) +{ + gint32 ret; + gchar *service_name = NULL; + g_return_val_if_fail (THRIFT_IS_MULTIPLEXED_PROTOCOL (protocol), -1); + + ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (protocol); + ThriftMultiplexedProtocolClass *multiplexClass = THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(self); + ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (multiplexClass); + + if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) { + service_name = g_strdup_printf("%s%s%s", self->service_name, self->separator, name); + + }else{ + service_name = g_strdup(name); + } + + // relay to the protocol_decorator + ret = thrift_protocol_decorator_write_message_begin(protocol, service_name, message_type, seqid, error); + + g_free(service_name); + + return ret; +} + + + + +static void +thrift_multiplexed_protocol_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object); + + switch (property_id) + { + case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME: + if(self->service_name!=NULL) + g_free (self->service_name); + self->service_name= g_value_dup_string (value); + break; + + case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR: + if(self->separator!=NULL) + g_free (self->separator); + self->separator= g_value_dup_string (value); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +thrift_multiplexed_protocol_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (object); + + switch (property_id) + { + case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME: + g_value_set_string (value, self->service_name); + break; + + case PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR: + g_value_set_string (value, self->separator); + break; + + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void +thrift_multiplexed_protocol_init (ThriftMultiplexedProtocol *protocol) +{ + // THRIFT_UNUSED_VAR (protocol); + protocol->separator = g_strdup (THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR); + protocol->service_name = NULL; +} + +static void +thrift_multiplexed_protocol_finalize (ThriftMultiplexedProtocol *protocol) +{ + if(protocol->separator){ + g_free(protocol->separator); + protocol->separator = NULL; + } + if(protocol->service_name){ + g_free(protocol->service_name); + protocol->service_name = NULL; + } + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the dispose() virtual function: it is + * always guaranteed to do so + */ + /* This fails, why? G_OBJECT_CLASS (protocol)->finalize(protocol); */ +} + + +/* initialize the class */ +static void +thrift_multiplexed_protocol_class_init (ThriftMultiplexedProtocolClass *klass) +{ + ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_debug("Current Multiplexed write_message_begin addr %p, new %p", cls->write_message_begin, thrift_multiplexed_protocol_write_message_begin); + cls->write_message_begin = thrift_multiplexed_protocol_write_message_begin; + + + object_class->set_property = thrift_multiplexed_protocol_set_property; + object_class->get_property = thrift_multiplexed_protocol_get_property; + object_class->finalize = thrift_multiplexed_protocol_finalize; + + thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SERVICE_NAME] = + g_param_spec_string ("service-name", + "Service name the protocol points to", + "Set the service name", + NULL /* default value */, + (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + thrift_multiplexed_protocol_obj_properties[PROP_THRIFT_MULTIPLEXED_PROTOCOL_SEPARATOR] = + g_param_spec_string ("separator", + "Separator for service name and pointer", + "Set service name separator", + NULL /* default value */, + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, + PROP_THRIFT_MULTIPLEXED_PROTOCOL_END, + thrift_multiplexed_protocol_obj_properties); +} http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h ---------------------------------------------------------------------- diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h new file mode 100644 index 0000000..58d86ce --- /dev/null +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _THRIFT_MULTIPLEXED_PROTOCOL_H +#define _THRIFT_MULTIPLEXED_PROTOCOL_H + +#include <glib-object.h> + +#include <thrift/c_glib/protocol/thrift_protocol.h> +#include <thrift/c_glib/protocol/thrift_protocol_decorator.h> +#include <thrift/c_glib/transport/thrift_transport.h> + +G_BEGIN_DECLS + +/*! \file thrift_multiplexed_protocol.h + * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the + * ThriftProtocol interface. + */ + +/* type macros */ +#define THRIFT_TYPE_MULTIPLEXED_PROTOCOL (thrift_multiplexed_protocol_get_type ()) +#define THRIFT_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocol)) +#define THRIFT_IS_MULTIPLEXED_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL)) +#define THRIFT_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass)) +#define THRIFT_IS_MULTIPLEXED_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROTOCOL)) +#define THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROTOCOL, ThriftMultiplexedProtocolClass)) + +/* version numbers */ +#define THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR ":" + +typedef struct _ThriftMultiplexedProtocol ThriftMultiplexedProtocol; + + + +/*! + * Thrift Multiplexed Protocol instance. + */ +struct _ThriftMultiplexedProtocol +{ + ThriftProtocolDecorator parent; + + gchar *service_name; + gchar *separator; +}; + +typedef struct _ThriftMultiplexedProtocolClass ThriftMultiplexedProtocolClass; + +/*! + * Thrift Multiplexed Protocol class. + */ +struct _ThriftMultiplexedProtocolClass +{ + ThriftProtocolDecoratorClass parent; +}; + +/* used by THRIFT_TYPE_MULTIPLEXED_PROTOCOL */ +GType thrift_multiplexed_protocol_get_type (void); + +G_END_DECLS + +#endif /* _THRIFT_MULTIPLEXED_PROTOCOL_H */ http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c ---------------------------------------------------------------------- diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c new file mode 100644 index 0000000..1844795 --- /dev/null +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c @@ -0,0 +1,651 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string.h> +#include <stdio.h> +#include <glib.h> +#include <glib-object.h> + +#include <thrift/c_glib/thrift.h> +#include <thrift/c_glib/protocol/thrift_protocol.h> +#include <thrift/c_glib/protocol/thrift_binary_protocol.h> +#include <thrift/c_glib/protocol/thrift_protocol_decorator.h> + +G_DEFINE_TYPE(ThriftProtocolDecorator, thrift_protocol_decorator, THRIFT_TYPE_PROTOCOL) + + +enum +{ + PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL = 1, + PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END +}; + +static GParamSpec *thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END] = { NULL, }; + + + + + +gint32 +thrift_protocol_decorator_write_message_begin (ThriftProtocol *protocol, + const gchar *name, + const ThriftMessageType message_type, + const gint32 seqid, GError **error) +{ + + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + ThriftProtocolClass *proto = THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol); + + g_info("Concrete protocol %p | %p", self->concrete_protocol, proto); + + return proto->write_message_begin (self->concrete_protocol, name, + message_type, seqid, + error); +} + +gint32 +thrift_protocol_decorator_write_message_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_message_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_struct_begin (ThriftProtocol *protocol, const gchar *name, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_begin (self->concrete_protocol, + name, error); +} + +gint32 +thrift_protocol_decorator_write_struct_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_struct_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_field_begin (ThriftProtocol *protocol, + const gchar *name, + const ThriftType field_type, + const gint16 field_id, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_begin (self->concrete_protocol, + name, field_type, + field_id, error); +} + +gint32 +thrift_protocol_decorator_write_field_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_field_stop (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_field_stop (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_map_begin (ThriftProtocol *protocol, + const ThriftType key_type, + const ThriftType value_type, + const guint32 size, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_begin (self->concrete_protocol, + key_type, value_type, + size, error); +} + +gint32 +thrift_protocol_decorator_write_map_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_map_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_list_begin (ThriftProtocol *protocol, + const ThriftType element_type, + const guint32 size, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_begin (self->concrete_protocol, + element_type, size, + error); +} + +gint32 +thrift_protocol_decorator_write_list_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_list_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_set_begin (ThriftProtocol *protocol, + const ThriftType element_type, + const guint32 size, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_begin (self->concrete_protocol, + element_type, size, + error); +} + +gint32 +thrift_protocol_decorator_write_set_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_set_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_write_bool (ThriftProtocol *protocol, + const gboolean value, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_bool (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_write_byte (ThriftProtocol *protocol, const gint8 value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_byte (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_write_i16 (ThriftProtocol *protocol, const gint16 value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i16 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_write_i32 (ThriftProtocol *protocol, const gint32 value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i32 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_write_i64 (ThriftProtocol *protocol, const gint64 value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_i64 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_write_double (ThriftProtocol *protocol, + const gdouble value, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_double (self->concrete_protocol, + value, error); +} + +gint32 +thrift_protocol_decorator_write_string (ThriftProtocol *protocol, + const gchar *str, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_string (self->concrete_protocol, str, + error); +} + +gint32 +thrift_protocol_decorator_write_binary (ThriftProtocol *protocol, const gpointer buf, + const guint32 len, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->write_binary (self->concrete_protocol, buf, + len, error); +} + +gint32 +thrift_protocol_decorator_read_message_begin (ThriftProtocol *protocol, + gchar **name, + ThriftMessageType *message_type, + gint32 *seqid, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_begin (self->concrete_protocol, + name, message_type, + seqid, error); +} + +gint32 +thrift_protocol_decorator_read_message_end (ThriftProtocol *protocol, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_message_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_struct_begin (ThriftProtocol *protocol, + gchar **name, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_begin (self->concrete_protocol, + name, + error); +} + +gint32 +thrift_protocol_decorator_read_struct_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_struct_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_field_begin (ThriftProtocol *protocol, + gchar **name, + ThriftType *field_type, + gint16 *field_id, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_begin (self->concrete_protocol, + name, + field_type, + field_id, + error); +} + +gint32 +thrift_protocol_decorator_read_field_end (ThriftProtocol *protocol, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_field_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_map_begin (ThriftProtocol *protocol, + ThriftType *key_type, + ThriftType *value_type, guint32 *size, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_begin (self->concrete_protocol, + key_type, + value_type, + size, + error); +} + +gint32 +thrift_protocol_decorator_read_map_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_map_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_list_begin (ThriftProtocol *protocol, + ThriftType *element_type, + guint32 *size, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_begin (self->concrete_protocol, + element_type, + size, error); +} + +gint32 +thrift_protocol_decorator_read_list_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_list_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_set_begin (ThriftProtocol *protocol, + ThriftType *element_type, + guint32 *size, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_begin (self->concrete_protocol, + element_type, + size, error); +} + +gint32 +thrift_protocol_decorator_read_set_end (ThriftProtocol *protocol, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_set_end (self->concrete_protocol, + error); +} + +gint32 +thrift_protocol_decorator_read_bool (ThriftProtocol *protocol, gboolean *value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_bool (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_byte (ThriftProtocol *protocol, gint8 *value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_byte (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_i16 (ThriftProtocol *protocol, gint16 *value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i16 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_i32 (ThriftProtocol *protocol, gint32 *value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i32 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_i64 (ThriftProtocol *protocol, gint64 *value, + GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_i64 (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_double (ThriftProtocol *protocol, + gdouble *value, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_double (self->concrete_protocol, value, + error); +} + +gint32 +thrift_protocol_decorator_read_string (ThriftProtocol *protocol, + gchar **str, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_string (self->concrete_protocol, str, + error); +} + +gint32 +thrift_protocol_decorator_read_binary (ThriftProtocol *protocol, gpointer *buf, + guint32 *len, GError **error) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + return THRIFT_PROTOCOL_GET_CLASS (self->concrete_protocol)->read_binary (self->concrete_protocol, buf, + len, error); +} + + +static void +thrift_protocol_decorator_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object); + g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object)); + + switch (property_id) + { + case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL: + // FIXME We must finalize it first + //g_clear_object (&self->concrete_protocol); + self->concrete_protocol=g_value_get_pointer (value); + g_info("Setting concrete protocol %p to %p in %s",self, self->concrete_protocol, g_type_name(G_TYPE_FROM_INSTANCE(object))); + // We must get the transport and set it on base class. + + break; + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +thrift_protocol_decorator_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object); + g_info("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object)); + + switch (property_id) + { + case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL: + g_value_set_pointer (value, self->concrete_protocol); + + /* But we must also set our */ + + break; + default: + /* We don't have any other property... */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +ThriftProtocol * +thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol) +{ + ThriftProtocol *retval = NULL; + if(!THRIFT_IS_PROTOCOL_DECORATOR(protocol)){ + g_warning("The type is not protocol decorator"); + return NULL; + } + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR(protocol); + g_info("Getting concrete protocol from %X -> %X", self, self->concrete_protocol); + + return retval; +} + + +static void +thrift_protocol_decorator_init (ThriftProtocolDecorator *protocol) +{ + protocol->concrete_protocol = NULL; +} + + + +static void +thrift_protocol_decorator_dispose (ThriftProtocolDecorator *protocol) +{ + ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (protocol); + + /* dispose() might be called multiple times, so we must guard against + * calling g_object_unref() on an invalid GObject by setting the member + * NULL; g_clear_object() does this for us. + */ + if(self->concrete_protocol!=NULL) + g_clear_object (&self->concrete_protocol); +} + +static void +thrift_protocol_decorator_finalize (ThriftProtocolDecorator *protocol) +{ + +// /* +// * Chain the concrete protocol finalize +// */ +// if(protocol->concrete_protocol!=NULL){ +// G_OBJECT_CLASS (protocol->concrete_protocol)->finalize(protocol->concrete_protocol); +// } + /* Always chain up to the parent class; there is no need to check if + * the parent class implements the finalize() virtual function: it is + * always guaranteed to do so + */ + G_OBJECT_CLASS (protocol)->finalize(protocol); +} + +/* initialize the class */ +static void +thrift_protocol_decorator_class_init (ThriftProtocolDecoratorClass *klass) +{ + ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->set_property = thrift_protocol_decorator_set_property; + object_class->get_property = thrift_protocol_decorator_get_property; + object_class->finalize = thrift_protocol_decorator_finalize; + object_class->dispose = thrift_protocol_decorator_dispose; + + thrift_protocol_decorator_obj_properties[PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL] = + g_param_spec_pointer ("protocol", + "Protocol", + "Set the protocol to be implemented", + (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + + g_object_class_install_properties (object_class, + PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_END, + thrift_protocol_decorator_obj_properties); + + g_info("Current decorator write_message_begin addr %p, new %p", cls->write_message_begin, thrift_protocol_decorator_write_message_begin); + + + cls->write_message_begin = thrift_protocol_decorator_write_message_begin; + cls->write_message_end = thrift_protocol_decorator_write_message_end; + cls->write_struct_begin = thrift_protocol_decorator_write_struct_begin; + cls->write_struct_end = thrift_protocol_decorator_write_struct_end; + cls->write_field_begin = thrift_protocol_decorator_write_field_begin; + cls->write_field_end = thrift_protocol_decorator_write_field_end; + cls->write_field_stop = thrift_protocol_decorator_write_field_stop; + cls->write_map_begin = thrift_protocol_decorator_write_map_begin; + cls->write_map_end = thrift_protocol_decorator_write_map_end; + cls->write_list_begin = thrift_protocol_decorator_write_list_begin; + cls->write_list_end = thrift_protocol_decorator_write_list_end; + cls->write_set_begin = thrift_protocol_decorator_write_set_begin; + cls->write_set_end = thrift_protocol_decorator_write_set_end; + cls->write_bool = thrift_protocol_decorator_write_bool; + cls->write_byte = thrift_protocol_decorator_write_byte; + cls->write_i16 = thrift_protocol_decorator_write_i16; + cls->write_i32 = thrift_protocol_decorator_write_i32; + cls->write_i64 = thrift_protocol_decorator_write_i64; + cls->write_double = thrift_protocol_decorator_write_double; + cls->write_string = thrift_protocol_decorator_write_string; + cls->write_binary = thrift_protocol_decorator_write_binary; + cls->read_message_begin = thrift_protocol_decorator_read_message_begin; + cls->read_message_end = thrift_protocol_decorator_read_message_end; + cls->read_struct_begin = thrift_protocol_decorator_read_struct_begin; + cls->read_struct_end = thrift_protocol_decorator_read_struct_end; + cls->read_field_begin = thrift_protocol_decorator_read_field_begin; + cls->read_field_end = thrift_protocol_decorator_read_field_end; + cls->read_map_begin = thrift_protocol_decorator_read_map_begin; + cls->read_map_end = thrift_protocol_decorator_read_map_end; + cls->read_list_begin = thrift_protocol_decorator_read_list_begin; + cls->read_list_end = thrift_protocol_decorator_read_list_end; + cls->read_set_begin = thrift_protocol_decorator_read_set_begin; + cls->read_set_end = thrift_protocol_decorator_read_set_end; + cls->read_bool = thrift_protocol_decorator_read_bool; + cls->read_byte = thrift_protocol_decorator_read_byte; + cls->read_i16 = thrift_protocol_decorator_read_i16; + cls->read_i32 = thrift_protocol_decorator_read_i32; + cls->read_i64 = thrift_protocol_decorator_read_i64; + cls->read_double = thrift_protocol_decorator_read_double; + cls->read_string = thrift_protocol_decorator_read_string; + cls->read_binary = thrift_protocol_decorator_read_binary; +} http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h ---------------------------------------------------------------------- diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h new file mode 100644 index 0000000..8eb6bac --- /dev/null +++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.h @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _THRIFT_PROTOCOL_DECORATOR_H +#define _THRIFT_PROTOCOL_DECORATOR_H + +#include <glib-object.h> + +#include <thrift/c_glib/protocol/thrift_protocol.h> +#include <thrift/c_glib/transport/thrift_transport.h> + +G_BEGIN_DECLS + +/*! \file thrift_protocol_decorator.h + * \brief Multiplexed protocol implementation of a Thrift protocol. Implements the + * ThriftProtocol interface. + */ + +/* type macros */ +#define THRIFT_TYPE_PROTOCOL_DECORATOR (thrift_protocol_decorator_get_type ()) +#define THRIFT_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecorator)) +#define THRIFT_IS_PROTOCOL_DECORATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR)) +#define THRIFT_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass)) +#define THRIFT_IS_PROTOCOL_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_PROTOCOL_DECORATOR)) +#define THRIFT_PROTOCOL_DECORATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_PROTOCOL_DECORATOR, ThriftProtocolDecoratorClass)) + +typedef struct _ThriftProtocolDecorator ThriftProtocolDecorator; + + +/*! + * Thrift Multiplexed Protocol instance. + */ +struct _ThriftProtocolDecorator +{ + ThriftProtocol parent; + + ThriftProtocol *concrete_protocol; +}; + +typedef struct _ThriftProtocolDecoratorClass ThriftProtocolDecoratorClass; + +/*! + * Thrift Multiplexed Protocol class. + */ +struct _ThriftProtocolDecoratorClass +{ + ThriftProtocolClass parent; + +}; + +/* used by THRIFT_TYPE_PROTOCOL_DECORATOR */ +GType thrift_protocol_decorator_get_type (void); + + +ThriftProtocol * +thrift_protocol_decorator_get_concrete_protocol(ThriftProtocolDecorator *protocol); + + +G_END_DECLS + +#endif /* _THRIFT_PROTOCOL_DECORATOR_H */ http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/lib/java/test/org/apache/thrift/test/TestServer.java ---------------------------------------------------------------------- diff --git a/lib/java/test/org/apache/thrift/test/TestServer.java b/lib/java/test/org/apache/thrift/test/TestServer.java index 14cd2ab..f4defad 100644 --- a/lib/java/test/org/apache/thrift/test/TestServer.java +++ b/lib/java/test/org/apache/thrift/test/TestServer.java @@ -30,6 +30,7 @@ import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; +import org.apache.thrift.protocol.TMultiplexedProtocol; import org.apache.thrift.server.ServerContext; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TServer.Args; @@ -46,10 +47,11 @@ import org.apache.thrift.transport.TSSLTransportFactory; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.TNonblockingServerSocket; - +import org.apache.thrift.TMultiplexedProcessor; import thrift.test.Insanity; import thrift.test.Numberz; +import thrift.test.SecondService; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; @@ -58,6 +60,25 @@ import thrift.test.Xtruct2; public class TestServer { + // Multiplexed Protocol Support Details: + // + // For multiplexed testing we always use binary protocol underneath. + // + // "ThriftTest" named service implements ThriftTest from ThriftTest.thrift + // "Second" named service implements "SecondService" from ThriftTest.thrift + + static class SecondHandler implements thrift.test.SecondService.Iface { + + @Override + public void blahBlah() throws org.apache.thrift.TException + { throw new org.apache.thrift.TException("blahBlah"); } + + @Override + public java.lang.String secondtestString(java.lang.String thing) throws org.apache.thrift.TException + { return "testString(\"" + thing + "\")"; } + + } + static class TestServerContext implements ServerContext { int connectionId; @@ -139,7 +160,7 @@ public class TestServer { System.out.println(" --help\t\t\tProduce help message"); System.out.println(" --port=arg (=" + port + ")\tPort number to connect"); System.out.println(" --transport=arg (=" + transport_type + ")\n\t\t\t\tTransport: buffered, framed, fastframed"); - System.out.println(" --protocol=arg (=" + protocol_type + ")\tProtocol: binary, json, compact"); + System.out.println(" --protocol=arg (=" + protocol_type + ")\tProtocol: binary, compact, json, multiplexed"); System.out.println(" --ssl\t\t\tEncrypted Transport using SSL"); System.out.println(" --server-type=arg (=" + server_type +")\n\t\t\t\tType of server: simple, thread-pool, nonblocking, threaded-selector"); System.out.println(" --string-limit=arg (=" + string_limit + ")\tString read length limit"); @@ -167,8 +188,9 @@ public class TestServer { throw new Exception("Unknown server type! " + server_type); } if (protocol_type.equals("binary")) { - } else if (protocol_type.equals("json")) { } else if (protocol_type.equals("compact")) { + } else if (protocol_type.equals("json")) { + } else if (protocol_type.equals("multiplexed")) { } else { throw new Exception("Unknown protocol type! " + protocol_type); } @@ -183,11 +205,12 @@ public class TestServer { System.exit(1); } - // Processor - TestHandler testHandler = - new TestHandler(); - ThriftTest.Processor testProcessor = - new ThriftTest.Processor(testHandler); + // Processors + TestHandler testHandler = new TestHandler(); + ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); + + SecondHandler secondHandler = new SecondHandler(); + SecondService.Processor secondProcessor = new SecondService.Processor(secondHandler); // Protocol factory TProtocolFactory tProtocolFactory = null; @@ -195,7 +218,7 @@ public class TestServer { tProtocolFactory = new TJSONProtocol.Factory(); } else if (protocol_type.equals("compact")) { tProtocolFactory = new TCompactProtocol.Factory(string_limit, container_limit); - } else { + } else { // also covers multiplexed tProtocolFactory = new TBinaryProtocol.Factory(string_limit, container_limit); } @@ -211,6 +234,10 @@ public class TestServer { TServer serverEngine = null; + // If we are multiplexing services in one server... + TMultiplexedProcessor multiplexedProcessor = new TMultiplexedProcessor(); + multiplexedProcessor.registerProcessor("ThriftTest", testProcessor); + multiplexedProcessor.registerProcessor("Second", secondProcessor); if (server_type.equals("nonblocking") || server_type.equals("threaded-selector")) { @@ -218,23 +245,21 @@ public class TestServer { TNonblockingServerSocket tNonblockingServerSocket = new TNonblockingServerSocket(new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(port)); - if (server_type.equals("nonblocking")) { + if (server_type.contains("nonblocking")) { // Nonblocking Server TNonblockingServer.Args tNonblockingServerArgs = new TNonblockingServer.Args(tNonblockingServerSocket); - tNonblockingServerArgs.processor(testProcessor); + tNonblockingServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor); tNonblockingServerArgs.protocolFactory(tProtocolFactory); tNonblockingServerArgs.transportFactory(tTransportFactory); - serverEngine = new TNonblockingServer(tNonblockingServerArgs); } else { // server_type.equals("threaded-selector") // ThreadedSelector Server TThreadedSelectorServer.Args tThreadedSelectorServerArgs = new TThreadedSelectorServer.Args(tNonblockingServerSocket); - tThreadedSelectorServerArgs.processor(testProcessor); + tThreadedSelectorServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor); tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory); tThreadedSelectorServerArgs.transportFactory(tTransportFactory); - serverEngine = new TThreadedSelectorServer(tThreadedSelectorServerArgs); } } else { @@ -251,25 +276,22 @@ public class TestServer { if (server_type.equals("simple")) { // Simple Server TServer.Args tServerArgs = new TServer.Args(tServerSocket); - tServerArgs.processor(testProcessor); + tServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor); tServerArgs.protocolFactory(tProtocolFactory); tServerArgs.transportFactory(tTransportFactory); - serverEngine = new TSimpleServer(tServerArgs); } else { // server_type.equals("threadpool") // ThreadPool Server TThreadPoolServer.Args tThreadPoolServerArgs = new TThreadPoolServer.Args(tServerSocket); - tThreadPoolServerArgs.processor(testProcessor); + tThreadPoolServerArgs.processor(protocol_type.equals("multiplexed") ? multiplexedProcessor : testProcessor); tThreadPoolServerArgs.protocolFactory(tProtocolFactory); tThreadPoolServerArgs.transportFactory(tTransportFactory); - serverEngine = new TThreadPoolServer(tThreadPoolServerArgs); } } - - //Set server event handler + // Set server event handler serverEngine.setServerEventHandler(new TestServerEventHandler()); // Run it http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/c_glib/src/test_client.c ---------------------------------------------------------------------- diff --git a/test/c_glib/src/test_client.c b/test/c_glib/src/test_client.c index 9713e8c..a6ef869 100644 --- a/test/c_glib/src/test_client.c +++ b/test/c_glib/src/test_client.c @@ -28,6 +28,7 @@ #include <thrift/c_glib/thrift.h> #include <thrift/c_glib/protocol/thrift_binary_protocol.h> #include <thrift/c_glib/protocol/thrift_compact_protocol.h> +#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h> #include <thrift/c_glib/transport/thrift_buffered_transport.h> #include <thrift/c_glib/transport/thrift_framed_transport.h> #include <thrift/c_glib/transport/thrift_ssl_socket.h> @@ -73,6 +74,32 @@ gint32_compare (gconstpointer a, gconstpointer b) return result; } +/** + * It gets a multiplexed protocol which uses binary underneath + * @param transport the underlying transport + * @param service_name the single supported service name + * @todo need to allow multiple services to fully test multiplexed + * @return a multiplexed protocol wrapping the correct underlying protocol + */ +ThriftProtocol * +get_multiplexed_protocol(ThriftTransport *transport, gchar *service_name) +{ + ThriftProtocol * result_protocol=NULL; + ThriftProtocol * multiplexed_protocol=NULL; + + multiplexed_protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, + "transport", transport, + NULL); + + result_protocol = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROTOCOL, + "transport", transport, + "protocol", multiplexed_protocol, + "service-name", service_name, + NULL); + + return result_protocol; +} + int main (int argc, char **argv) { @@ -94,7 +121,7 @@ main (int argc, char **argv) { "transport", 't', 0, G_OPTION_ARG_STRING, &transport_option, "Transport: buffered, framed (=buffered)", NULL }, { "protocol", 'r', 0, G_OPTION_ARG_STRING, &protocol_option, - "Protocol: binary, compact (=binary)", NULL }, + "Protocol: binary, compact, multiplexed (=binary)", NULL }, { "testloops", 'n', 0, G_OPTION_ARG_INT, &num_tests, "Number of tests (=1)", NULL }, { NULL } @@ -153,7 +180,14 @@ main (int argc, char **argv) protocol_type = THRIFT_TYPE_COMPACT_PROTOCOL; protocol_name = "compact"; } - else if (strncmp (protocol_option, "binary", 7) != 0) { + else if (strncmp (protocol_option, "multiplexed", 12) == 0) { + protocol_type = THRIFT_TYPE_MULTIPLEXED_PROTOCOL; + protocol_name = "multiplexed(binary)"; + } + else if (strncmp (protocol_option, "binary", 7) == 0) { + printf("We are going with default binary protocol"); + } + else { fprintf (stderr, "Unknown protocol type %s\n", protocol_option); options_valid = FALSE; } @@ -213,9 +247,22 @@ main (int argc, char **argv) transport = g_object_new (transport_type, "transport", socket, NULL); - protocol = g_object_new (protocol_type, - "transport", transport, - NULL); + + if(protocol_type==THRIFT_TYPE_MULTIPLEXED_PROTOCOL) { + // TODO: A multiplexed test should also test "Second" (see Java TestServer) + // The context comes from the name of the thrift file. If multiple thrift + // schemas are used we have to redo the way this is done. + protocol = get_multiplexed_protocol(transport, "ThriftTest"); + if (NULL == protocol) { + g_object_unref (transport); + g_object_unref (socket); + return 252; + } + }else{ + protocol = g_object_new (protocol_type, + "transport", transport, + NULL); + } test_client = g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/crossrunner/report.py ---------------------------------------------------------------------- diff --git a/test/crossrunner/report.py b/test/crossrunner/report.py index cc5f26f..26f7d9e 100644 --- a/test/crossrunner/report.py +++ b/test/crossrunner/report.py @@ -104,7 +104,7 @@ class TestReporter(object): def _print_bar(self, out=None): print( - '==========================================================================', + '===============================================================================', file=(out or self.out)) def _print_exec_time(self): @@ -259,14 +259,14 @@ class SummaryReporter(TestReporter): name = '%s-%s' % (test.server.name, test.client.name) trans = '%s-%s' % (test.transport, test.socket) if not with_result: - return '{:24s}{:13s}{:25s}'.format(name[:23], test.protocol[:12], trans[:24]) + return '{:24s}{:18s}{:25s}'.format(name[:23], test.protocol[:17], trans[:24]) else: - return '{:24s}{:13s}{:25s}{:s}\n'.format(name[:23], test.protocol[:12], trans[:24], self._result_string(test)) + return '{:24s}{:18s}{:25s}{:s}\n'.format(name[:23], test.protocol[:17], trans[:24], self._result_string(test)) def _print_test_header(self): self._print_bar() print( - '{:24s}{:13s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'), + '{:24s}{:18s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'), file=self.out) def _print_header(self): http://git-wip-us.apache.org/repos/asf/thrift/blob/bc0082e0/test/tests.json ---------------------------------------------------------------------- diff --git a/test/tests.json b/test/tests.json index f1d6a47..2ab2e1d 100644 --- a/test/tests.json +++ b/test/tests.json @@ -13,6 +13,9 @@ "command": [ "test_client" ], + "protocols": [ + "multiplexed" + ], "sockets": [ "ip-ssl" ] @@ -106,7 +109,10 @@ ], "server": { "delay": 10, - "extra_args": ["run-testserver"] + "extra_args": ["run-testserver"], + "protocols": [ + "multiplexed" + ] }, "client": { "timeout": 13, @@ -125,8 +131,8 @@ "ip-ssl" ], "protocols": [ - "compact", "binary", + "compact", "json" ], "workdir": "../lib/java"