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
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 @@
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_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 \
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);
+}
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 */
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;
+}
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 */
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.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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
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 @@
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 @@
{ "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 @@
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 @@
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,
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 @@
def _print_bar(self, out=None):
print(
- '==========================================================================',
+ '===============================================================================',
file=(out or self.out))
def _print_exec_time(self):
@@ -259,14 +259,14 @@
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):
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"