diff --git a/python/osgiservicebridge/README.rst b/python/osgiservicebridge/README.rst index 0cac980..09f7516 100644 --- a/python/osgiservicebridge/README.rst +++ b/python/osgiservicebridge/README.rst @@ -1 +1 @@ -Python code for the ECF Py4j remote services provider. This code depends upon Py4j versions 0.10.6 and above. +Python code for the ECF Py4j remote services provider. This code depends upon Py4j versions 0.10.6 and above and Google Protocol Buffers 3.3.0 and above. diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/__init__.py b/python/osgiservicebridge/build/lib/osgiservicebridge/__init__.py index 9e56686..6a62158 100644 --- a/python/osgiservicebridge/build/lib/osgiservicebridge/__init__.py +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/__init__.py @@ -1,9 +1,10 @@ ''' -OSGi service bridge +OSGi service bridge Google protocol buffers (protobuf) support :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 - Copyright 2016 Composent, Inc. and others +:version: 1.2.0 + Copyright 2017 Composent, Inc. and others Licensed 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 diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/bridge.py b/python/osgiservicebridge/build/lib/osgiservicebridge/bridge.py index 94c04a4..7d35059 100644 --- a/python/osgiservicebridge/build/lib/osgiservicebridge/bridge.py +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/bridge.py @@ -1,9 +1,9 @@ ''' -OSGi service bridge Py4j classes +OSGi service bridge Google protocol buffers (protobuf) support :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 -:version: 1.0.0 +:version: 1.2.0 Copyright 2017 Composent, Inc. and others Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. ''' - from osgiservicebridge.version import __version__ as __v__ # Version __version__ = __v__ @@ -159,6 +158,9 @@ class Py4jServiceBridgeEventListener(object): these methods, and then providing their listener instance to the Py4jServiceBridge instance creation''' + def __init__(self): + super(Py4jServiceBridgeEventListener,self).__init__() + def service_imported(self, servicebridge, endpointid, proxy, endpoint_props): ''' Service imported notification. @@ -257,7 +259,7 @@ def __init__(self,service_listener=None,connection_listener=None,gateway_paramet self._map_converter = MapConverter() self._list_converter = ListConverter() self._service_listener = service_listener - self._connection_listener = None + self._connection_listener = connection_listener self._connection = None self._gateway_parameters = gateway_parameters self._callback_server_parameters = callback_server_parameters @@ -376,8 +378,6 @@ def get_jvm(self): Get the Py4JService Gateway's JVM :return: The Gateway's jvm ''' - with self._lock: - self._raise_not_connected(); return self._gateway.jvm def get_gateway(self): @@ -385,8 +385,6 @@ def get_gateway(self): Get the Py4JService JavaGateway :return: The Gateway ''' - with self._lock: - self._raise_not_connected() return self._gateway def get_callback_server_parameters(self): @@ -490,14 +488,13 @@ def _external_undiscoverService(self,props): self._bridge._unimport_service_from_java(props) def _call_endpoint(self,rsId,methodName,serializedArgs): - try: - endpoint = self._bridge.get_export_endpoint_for_rsid(rsId) - if endpoint: - return endpoint._raw_bytes_from_java(methodName,serializedArgs) - raise Exception('exception executing _raw_bytes_from_java') - except Exception as e: - _logger.error("Exception in _call_endpoint",e) - raise e + endpoint = self._bridge.get_export_endpoint_for_rsid(rsId) + if endpoint: + return endpoint._raw_bytes_from_java(methodName,serializedArgs) + else: + msg = 'No endpoint for rsId=%s methodName=%s serializedArgs=%s' % (rsId,methodName,serializedArgs) + _logger.error(msg) + raise Exception(msg) class Java: implements = [JAVA_DIRECT_ENDPOINT_CLASS, PY4J_CALL_BY_VALUE_CLASS] @@ -686,3 +683,56 @@ def __unexport(self,props): except Exception as e: _logger.error(e) raise e + +class JavaRemoteService(object): + + def __init__(self,endpoint_props,proxy): + self._endpoint_props = endpoint_props + self._proxy = proxy + + def get_endpoint_props(self): + return self._endpoint_props + + def get_proxy(self): + return self._proxy + + def get_objectclass(self): + return self._endpoint_props[osgiservicebridge.OBJECT_CLASS] + + def has_service(self,interface): + return (interface in self.get_objectclass()) + + def get_endpointid(self): + return self._endpoint_props(osgiservicebridge.ENDPOINT_ID) + +class JavaRemoteServiceRegistry(object): + + def __init__(self): + super(JavaRemoteServiceRegistry,self).__init__() + self._lock = RLock() + self._remote_services = {} + + def _add_remoteservice(self,endpoint_props,proxy): + with self._lock: + self._remote_services[endpoint_props[osgiservicebridge.ENDPOINT_ID]] = JavaRemoteService(endpoint_props,proxy) + + def _remove_remoteservice(self,endpointid): + with self._lock: + return self._remote_services.pop(endpointid) + + def _modify_remoteservice(self,endpointid,endpoint_props): + with self._lock: + rs = self._remote_services[endpointid] + if rs: + self._remote_services[endpointid] = JavaRemoteService(endpoint_props,rs.get_proxy()) + return rs + return None + + def _dispose(self): + with self._lock: + self._remote_services.clear() + + def lookup_services(self,interface): + with self._lock: + return [rs for rs in self._remote_services.values() if rs.has_service(interface)] + diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/exporter_pb2.py b/python/osgiservicebridge/build/lib/osgiservicebridge/exporter_pb2.py new file mode 100644 index 0000000..204c7a7 --- /dev/null +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/exporter_pb2.py @@ -0,0 +1,326 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: exporter.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='exporter.proto', + package='org.eclipse.ecf.python.protobuf', + syntax='proto2', + serialized_pb=_b('\n\x0e\x65xporter.proto\x12\x1forg.eclipse.ecf.python.protobuf\"\xf0\x02\n\rExportRequest\x12\x13\n\x0bmodule_name\x18\x01 \x01(\t\x12\x12\n\nclass_name\x18\x02 \x02(\t\x12W\n\rcreation_args\x18\x03 \x03(\x0b\x32@.org.eclipse.ecf.python.protobuf.ExportRequest.CreationArgsEntry\x12j\n\x17overriding_export_props\x18\x04 \x03(\x0b\x32I.org.eclipse.ecf.python.protobuf.ExportRequest.OverridingExportPropsEntry\x1a\x33\n\x11\x43reationArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a<\n\x1aOverridingExportPropsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"<\n\x0e\x45xportResponse\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x15\n\rerror_message\x18\x02 \x01(\t\"&\n\x0fUnexportRequest\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x02(\t\"I\n\x10UnexportResponse\x12\x13\n\x0b\x65ndpoint_id\x18\x01 \x01(\t\x12\x0f\n\x07success\x18\x02 \x02(\x08\x12\x0f\n\x07message\x18\x03 \x01(\t') +) + + + + +_EXPORTREQUEST_CREATIONARGSENTRY = _descriptor.Descriptor( + name='CreationArgsEntry', + full_name='org.eclipse.ecf.python.protobuf.ExportRequest.CreationArgsEntry', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.CreationArgsEntry.key', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='value', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.CreationArgsEntry.value', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=307, + serialized_end=358, +) + +_EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY = _descriptor.Descriptor( + name='OverridingExportPropsEntry', + full_name='org.eclipse.ecf.python.protobuf.ExportRequest.OverridingExportPropsEntry', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.OverridingExportPropsEntry.key', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='value', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.OverridingExportPropsEntry.value', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=360, + serialized_end=420, +) + +_EXPORTREQUEST = _descriptor.Descriptor( + name='ExportRequest', + full_name='org.eclipse.ecf.python.protobuf.ExportRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='module_name', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.module_name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='class_name', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.class_name', index=1, + number=2, type=9, cpp_type=9, label=2, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='creation_args', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.creation_args', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='overriding_export_props', full_name='org.eclipse.ecf.python.protobuf.ExportRequest.overriding_export_props', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_EXPORTREQUEST_CREATIONARGSENTRY, _EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY, ], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=52, + serialized_end=420, +) + + +_EXPORTRESPONSE = _descriptor.Descriptor( + name='ExportResponse', + full_name='org.eclipse.ecf.python.protobuf.ExportResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='endpoint_id', full_name='org.eclipse.ecf.python.protobuf.ExportResponse.endpoint_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='error_message', full_name='org.eclipse.ecf.python.protobuf.ExportResponse.error_message', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=422, + serialized_end=482, +) + + +_UNEXPORTREQUEST = _descriptor.Descriptor( + name='UnexportRequest', + full_name='org.eclipse.ecf.python.protobuf.UnexportRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='endpoint_id', full_name='org.eclipse.ecf.python.protobuf.UnexportRequest.endpoint_id', index=0, + number=1, type=9, cpp_type=9, label=2, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=484, + serialized_end=522, +) + + +_UNEXPORTRESPONSE = _descriptor.Descriptor( + name='UnexportResponse', + full_name='org.eclipse.ecf.python.protobuf.UnexportResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='endpoint_id', full_name='org.eclipse.ecf.python.protobuf.UnexportResponse.endpoint_id', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='success', full_name='org.eclipse.ecf.python.protobuf.UnexportResponse.success', index=1, + number=2, type=8, cpp_type=7, label=2, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='message', full_name='org.eclipse.ecf.python.protobuf.UnexportResponse.message', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=524, + serialized_end=597, +) + +_EXPORTREQUEST_CREATIONARGSENTRY.containing_type = _EXPORTREQUEST +_EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY.containing_type = _EXPORTREQUEST +_EXPORTREQUEST.fields_by_name['creation_args'].message_type = _EXPORTREQUEST_CREATIONARGSENTRY +_EXPORTREQUEST.fields_by_name['overriding_export_props'].message_type = _EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY +DESCRIPTOR.message_types_by_name['ExportRequest'] = _EXPORTREQUEST +DESCRIPTOR.message_types_by_name['ExportResponse'] = _EXPORTRESPONSE +DESCRIPTOR.message_types_by_name['UnexportRequest'] = _UNEXPORTREQUEST +DESCRIPTOR.message_types_by_name['UnexportResponse'] = _UNEXPORTRESPONSE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ExportRequest = _reflection.GeneratedProtocolMessageType('ExportRequest', (_message.Message,), dict( + + CreationArgsEntry = _reflection.GeneratedProtocolMessageType('CreationArgsEntry', (_message.Message,), dict( + DESCRIPTOR = _EXPORTREQUEST_CREATIONARGSENTRY, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.ExportRequest.CreationArgsEntry) + )) + , + + OverridingExportPropsEntry = _reflection.GeneratedProtocolMessageType('OverridingExportPropsEntry', (_message.Message,), dict( + DESCRIPTOR = _EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.ExportRequest.OverridingExportPropsEntry) + )) + , + DESCRIPTOR = _EXPORTREQUEST, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.ExportRequest) + )) +_sym_db.RegisterMessage(ExportRequest) +_sym_db.RegisterMessage(ExportRequest.CreationArgsEntry) +_sym_db.RegisterMessage(ExportRequest.OverridingExportPropsEntry) + +ExportResponse = _reflection.GeneratedProtocolMessageType('ExportResponse', (_message.Message,), dict( + DESCRIPTOR = _EXPORTRESPONSE, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.ExportResponse) + )) +_sym_db.RegisterMessage(ExportResponse) + +UnexportRequest = _reflection.GeneratedProtocolMessageType('UnexportRequest', (_message.Message,), dict( + DESCRIPTOR = _UNEXPORTREQUEST, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.UnexportRequest) + )) +_sym_db.RegisterMessage(UnexportRequest) + +UnexportResponse = _reflection.GeneratedProtocolMessageType('UnexportResponse', (_message.Message,), dict( + DESCRIPTOR = _UNEXPORTRESPONSE, + __module__ = 'exporter_pb2' + # @@protoc_insertion_point(class_scope:org.eclipse.ecf.python.protobuf.UnexportResponse) + )) +_sym_db.RegisterMessage(UnexportResponse) + + +_EXPORTREQUEST_CREATIONARGSENTRY.has_options = True +_EXPORTREQUEST_CREATIONARGSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) +_EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY.has_options = True +_EXPORTREQUEST_OVERRIDINGEXPORTPROPSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) +# @@protoc_insertion_point(module_scope) diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/flatbuf.py b/python/osgiservicebridge/build/lib/osgiservicebridge/flatbuf.py new file mode 100644 index 0000000..5741543 --- /dev/null +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/flatbuf.py @@ -0,0 +1,269 @@ +''' +OSGi service bridge Google protocol buffers (protobuf) support +:author: Scott Lewis +:copyright: Copyright 2016, Composent, Inc. +:license: Apache License 2.0 +:version: 1.2.0 + Copyright 2017 Composent, Inc. and others + Licensed 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. +''' +from functools import wraps +from logging import getLogger as getLibLogger +import sys +import osgiservicebridge +import time + +from flatbuffers import Builder + +# Documentation strings format +__docformat__ = "restructuredtext en" + +from osgiservicebridge.version import __version__ as __v__ +# Version +__version__ = __v__ + +# ------------------------------------------------------------------------------ +_logger = getLibLogger(__name__) +_timing = getLibLogger("timing."+__name__) +# ------------------------------------------------------------------------------ + +# PY2/PY3 version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +FB_SERVICE_EXPORTED_CONFIG_DEFAULT='ecf.py4j.host.python.fb' +FB_SERVICE_EXPORTED_CONFIGS_DEFAULT=[FB_SERVICE_EXPORTED_CONFIG_DEFAULT] + +FB_SERVICE_RETURN_TYPE_ATTR = '_return_type' +FB_SERVICE_ARG_TYPE_ATTR = '_arg_type' +FB_SERVICE_SOURCE_ATTR = '_source' +FB_FACTORY_METHOD_PREFIX = 'GetRootAs' + +def get_instance_method(instance, method_name): + ''' + Return the method_name function for instance. + :param instance: the instance to get the method from. Must not be None. + :param method_name: the method name (str) of the method to return. Must not be None. + :return: method with method_name on instance, None if not present. + ''' + return getattr(instance, method_name, None) + +def get_instance_type(instance, method_name, func_attr_name): + ''' + Return the class of the func_attr_name ('_return_type', or '_arg_type') on the method + with method_name on instance. + :param instance: the instance to query. Must not be None. + :param method_name: the method_name to access + :param func_attr_name: the function attr name, either '_return_type' or '_arg_type' + that has the class of the function's return type or argument type. + :return: the class of the function's return type or argument type based upon the func_attr_name + parameter. May be None if no function with given method_name on instance, or no + attribute on function with name func_attr_name. + ''' + f = get_instance_method(instance, method_name) + if not f: + return None + return getattr(f, func_attr_name, None) + +def get_instance_return_type(instance, method_name): + ''' + Return the class for the return_type for method_name on instance. + :param instance: the instance to query. Must not be None. + :param method_name: the method_name to access + :return: the class of the return type. Will be None if no function with method_name + or no return type attribute on function. + ''' + return get_instance_type(instance, method_name, FB_SERVICE_RETURN_TYPE_ATTR) + +def get_instance_arg_type(instance, method_name): + ''' + Return the class for the arg_type for method_name on instance. + :param instance: the instance to query. Must not be None. + :param method_name: the method_name to access. Must not be None. + :return: the class of the argument type. Will be None if no function with method_name + or no return type attribute on function. + ''' + return get_instance_type(instance, method_name, FB_SERVICE_ARG_TYPE_ATTR) + +def create_return_instance(instance, method_name): + ''' + Return a new instance of the appropriate return type for the given method + on the given instance. + :param instance: the instance to query. Must not be None. + :param method_name: the method name to access. Must not be None. + :return: new instance of return type for given method. Will return None + if there is no method_name on instance, or it does not have the + PB_SERVICE_RETURN_TYPE_ATTR on the function. + ''' + ret_type = get_instance_return_type(instance, method_name) + if ret_type is not None: + return ret_type() + return None + +def get_method_source(method): + return getattr(method,FB_SERVICE_SOURCE_ATTR, None) + +def set_method_source(method, sourcecode): + setattr(method, FB_SERVICE_ARG_TYPE_ATTR, sourcecode) + +def update_method(method,oldfunc,new_source): + if method: + setattr(method, FB_SERVICE_ARG_TYPE_ATTR, getattr(oldfunc, FB_SERVICE_ARG_TYPE_ATTR, None)) + setattr(method, FB_SERVICE_RETURN_TYPE_ATTR, getattr(oldfunc, FB_SERVICE_RETURN_TYPE_ATTR, None)) + setattr(method, FB_SERVICE_SOURCE_ATTR, new_source) + +def get_name_and_type_dict(m): + result = dict() + for key in m: + val = m[key] + if val is None: + result[key] = 'None' + else: + result[key] = fully_qualified_classname(type(val)) + return result + +def fully_qualified_classname(c): + module = c.__module__ + if module is None or module == str.__class__.__module__: + return c.__name__ + return module + '.' + c.__name__ + + +def _raw_bytes_from_java(self,methodName,serializedArgs): + return getattr(self,methodName)(serializedArgs) + +def argument_deserialize(argClass, serialized): + #If nothing to serialize, return None + if not serialized: + return None + argInst = None + #Then pass to parser and return + t0 = time.time() + try: + # Create fb staticmethod name + methodName = FB_FACTORY_METHOD_PREFIX+argClass.__name__ + method = getattr(argClass,methodName) + argInst = method(serialized,0) + except Exception as e: + _logger.exception('Class.'+methodName+' failed. argClass=%' % (argClass)) + raise e + t1 = time.time() + _timing.debug("flatbuf.request.deserialize;d="+str(1000*(t1-t0))+"ms") + return argInst + +def return_serialize(builder): + resBytes = None + t0 = time.time() + if builder: + try: + resBytes = builder.Output() + except Exception as e: + _logger.exception('builder.Output failed. builder=%s' % (builder)) + raise e + # If Python 2 we convert the string to bytearray + if PY2: + resBytes = bytearray(resBytes) + t1 = time.time() + _timing.debug("flatbuf.response.serialize;d="+str(1000*(t1-t0))+"ms") + return resBytes + +def flatbuf_remote_service(**kwargs): + ''' + Class decorator for flatbuf-based remote services. This class decorator is intended to be used as follows: + + @flatbuf_remote_service(objectClass=['fully.qualified.java.interface.package.Classname',...],export_properties={ 'myprop': 'myvalue' }) + class MyClass: + pass + + Example: + + @flatbuf_remote_service(objectClass=['org.eclipse.ecf.examples.protobuf.hello.IHello']) + class HelloServiceImpl: + + :param kwargs: the kwargs dict required to have 'objectClass' item and + and (optional) 'export_properties' item + ''' + def decorate(cls): + # setup the protocol buffers java-side config + pb_svc_props = { osgiservicebridge.SERVICE_EXPORTED_CONFIGS: FB_SERVICE_EXPORTED_CONFIGS_DEFAULT } + # get the 'service_properties' value from kwargs, if present + args_props = kwargs.pop(osgiservicebridge.EXPORT_PROPERTIES_NAME,None) + # if it is present, then merge/override with the values given + if args_props: + pb_svc_props = osgiservicebridge.merge_dicts(pb_svc_props,args_props) + # then set/reset the kwargs service_properties value + kwargs[osgiservicebridge.EXPORT_PROPERTIES_NAME] = pb_svc_props + # call _modify_remoteservice_class to modify the class itself (add Java inner + # class and set implements and service_properties values + cls = osgiservicebridge._modify_remoteservice_class(cls,kwargs) + # set pbbuffers callback to _raw_bytes_from_java + cls._raw_bytes_from_java = _raw_bytes_from_java + return cls + return decorate + +def flatbuf_remote_service_method(arg_type,return_type=None): + ''' + Method decorator for flatbuf-based remote services method. This class decorator is intended to be used as follows: + + @flatbuf_remote_service_method(arg_type=,return_type=) + def (self,): + + For example: + + @flatbuf_remote_service_method(arg_type=HelloMsgContent,return_type=HelloMsgContent) + def sayHello(self,pbarg): + + Where HelloMsgContent is a flatc-generated python class. When called, pbarg is guaranteed to be an + instance of a flatc-generated class. + The sayHello method is also required to return an instance of HelloMsgContent or None. + + :param arg_type: the class of the pbarg type (will be instance of HelloMsgContent) + ''' + def pbwrapper(func): + def logged_wrapped_exception(msg): + exc_type, exc_value, exc_traceback = sys.exc_info() + from traceback import format_exception + lines = format_exception(exc_type, exc_value, exc_traceback) + lines[1:2] = [] + _logger.error(msg + ('\n%s' % (''.join(lines)))) + + func._arg_type = arg_type + func._return_type = return_type + func._source = None + try: + from inspect import getsource + setattr(func, FB_SERVICE_SOURCE_ATTR, getsource(func)) + except: + pass + @wraps(func) + def wrapper(*args): + # set argClass to arg_type + argClass = arg_type + # signature should be: self,arg. Pass args[1]...the actual argument + # ...to deserialize byte[] into pb Message into argInst + argInst = argument_deserialize(argClass, args[1]) + builder = None + t0 = time.time() + try: + # Now actually call function, with self,pbMessage + builder = func(args[0],argInst) + except Exception as e: + logged_wrapped_exception('Remote method invoke failed') + raise e + t1 = time.time() + _timing.debug("flatbuf.exec;time="+str(1000*(t1-t0))+"ms") + if not func._return_type is None: + isinstance(builder,Builder) + return return_serialize(builder) + return wrapper + return pbwrapper + diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/protobuf.py b/python/osgiservicebridge/build/lib/osgiservicebridge/protobuf.py index e0bcb21..cb02e3e 100644 --- a/python/osgiservicebridge/build/lib/osgiservicebridge/protobuf.py +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/protobuf.py @@ -3,7 +3,7 @@ :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 -:version: 1.0.0 +:version: 1.2.0 Copyright 2017 Composent, Inc. and others Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,10 +17,21 @@ ''' from functools import wraps from logging import getLogger as getLibLogger - import sys import osgiservicebridge +from osgiservicebridge import ENDPOINT_PACKAGE_VERSION_ + +import time + from google.protobuf.message import Message +from google.protobuf.descriptor_pb2 import DescriptorProto +from google.protobuf.descriptor import MakeDescriptor +from google.protobuf.reflection import MakeClass +from osgiservicebridge.bridge import JavaRemoteServiceRegistry, Py4jServiceBridgeEventListener + +from osgiservicebridge import ECF_SERVICE_EXPORTED_ASYNC_INTERFACES + +from exporter_pb2 import ExportRequest,ExportResponse,UnexportRequest,UnexportResponse # Documentation strings format __docformat__ = "restructuredtext en" @@ -30,9 +41,8 @@ __version__ = __v__ # ------------------------------------------------------------------------------ - _logger = getLibLogger(__name__) - +_timing = getLibLogger("timing."+__name__) # ------------------------------------------------------------------------------ # PY2/PY3 version differentiation. @@ -40,11 +50,17 @@ PY3 = sys.version_info[0] == 3 PY34 = sys.version_info[0:2] >= (3, 4) -PB_SERVICE_EXPORTED_CONFIG_DEFAULT='ecf.py4j.host.python.pb' +JAVA_HOST_CONFIG_TYPE = 'ecf.py4j.host.pb'; +PYTHON_HOST_CONFIG_TYPE = 'ecf.py4j.host.python.pb'; +JAVA_CONSUMER_CONFIG_TYPE = 'ecf.py4j.consumer.pb'; +PYTHON_CONSUMER_CONFIG_TYPE = 'ecf.py4j.consumer.python.pb'; + +PB_SERVICE_EXPORTED_CONFIG_DEFAULT=PYTHON_HOST_CONFIG_TYPE PB_SERVICE_EXPORTED_CONFIGS_DEFAULT=[PB_SERVICE_EXPORTED_CONFIG_DEFAULT] PB_SERVICE_RETURN_TYPE_ATTR = '_return_type' PB_SERVICE_ARG_TYPE_ATTR = '_arg_type' +PB_SERVICE_SOURCE_ATTR = '_source' def get_instance_method(instance, method_name): ''' @@ -106,16 +122,19 @@ def create_return_instance(instance, method_name): if ret_type is not None: return ret_type() return None -''' -def instance_reset_function(instance, method_name, newfunc): - oldfunc = getattr(instance, method_name) - if oldfunc: - oldargtype = getattr(oldfunc, PB_SERVICE_ARG_TYPE_ATTR, None) - oldreturntype = getattr(oldfunc, PB_SERVICE_RETURN_TYPE_ATTR, None) - setattr(newfunc,PB_SERVICE_ARG_TYPE_ATTR, oldargtype) - setattr(newfunc,PB_SERVICE_RETURN_TYPE_ATTR, oldreturntype) - setattr(instance,method_name,newfunc) - ''' + +def get_method_source(method): + return getattr(method,PB_SERVICE_SOURCE_ATTR, None) + +def set_method_source(method, sourcecode): + setattr(method, PB_SERVICE_ARG_TYPE_ATTR, sourcecode) + +def update_method(method,oldfunc,new_source): + if method: + setattr(method, PB_SERVICE_ARG_TYPE_ATTR, getattr(oldfunc, PB_SERVICE_ARG_TYPE_ATTR, None)) + setattr(method, PB_SERVICE_RETURN_TYPE_ATTR, getattr(oldfunc, PB_SERVICE_RETURN_TYPE_ATTR, None)) + setattr(method, PB_SERVICE_SOURCE_ATTR, new_source) + def get_name_and_type_dict(m): result = dict() for key in m: @@ -132,51 +151,105 @@ def fully_qualified_classname(c): return c.__name__ return module + '.' + c.__name__ - def _raw_bytes_from_java(self,methodName,serializedArgs): + return getattr(self,methodName)(serializedArgs) + +def bytes_to_pmessage(pmessage_class, message_bytes): + if not message_bytes: + return None + pmessage_instance = None try: - return getattr(self,methodName)(serializedArgs) + pmessage_instance = pmessage_class() except Exception as e: - _logger.error('Exception calling methodName='+str(methodName)+" on object="+str(self)) + _logger.exception('bytes_to_pmessage could not create instance of message_class=%s' % (pmessage_class)) raise e + if PY2: + message_bytes = str(message_bytes) + #Then pass to parser and return + t0 = time.time() + try: + # deserialze + pmessage_instance.ParseFromString(message_bytes) + except Exception as e: + _logger.exception('bytes_to_pmessage could not parse message from bytes. message_instance=%' % (pmessage_instance)) + raise e + t1 = time.time() + _timing.debug("protobuf.bytes_to_pmessage;diff="+str(1000*(t1-t0))+"ms") + return pmessage_instance -def argument_deserialize(argClass, serialized): - #If nothing to serialze, return None - if not serialized: +def bytes_to_jmessage(jmessage_class, message_bytes): + if not message_bytes: return None - #First create a new instance of the given argClass - argInst = None + parser_instance = None try: - # create instance of argClass - argInst = argClass() + parser_method = jmessage_class.getMethod("parser", None) + parser_instance = parser_method.invoke(None,None) except Exception as e: - _logger.error('Could not create instance of class='+str(argClass), e) + _logger.exception('bytes_to_jmessage could not create instance of message_class=%s' % (jmessage_class)) raise e - # XXX because of problem discovered we check the Python version, - # If Python 2 we convert the serialized to a string (from bytearray) if PY2: - serialized = str(serialized) + message_bytes = bytearray(message_bytes) #Then pass to parser and return + t0 = time.time() + jmessage_instance = None try: # deserialze - argInst.ParseFromString(serialized) + jmessage_instance = parser_instance.parseFrom(message_bytes) except Exception as e: - _logger.error('Could not call ParseFromString on instance='+str(argInst),e) + _logger.exception('bytes_to_jmessage could not parse message from bytes. message_instance=%' % (jmessage_instance)) raise e - return argInst + t1 = time.time() + _timing.debug("protobuf.bytes_to_jmessage;ddiff="+str(1000*(t1-t0))+"ms") + return jmessage_instance + +def pmessage_to_bytes(pmessage): + pmessage_bytes = None + t0 = time.time() + if pmessage: + try: + pmessage_bytes = pmessage.SerializeToString() + except Exception as e: + _logger.exception('pmessage_to_bytes failed. pmessage=%s' % (pmessage)) + raise e + # If Python 2 we convert the string to bytearray + if PY2: + pmessage_bytes = bytearray(pmessage_bytes) + t1 = time.time() + _timing.debug("protobuf.pmessage_to_bytes;diff="+str(1000*(t1-t0))+"ms") + return pmessage_bytes -def return_serialize(respb): - resBytes = None - if respb: +def jmessage_to_bytes(jmessage): + jmessage_bytes = None + t0 = time.time() + if jmessage: try: - resBytes = respb.SerializeToString() + jmessage_bytes = jmessage.toByteArray() except Exception as e: - _logger.error('Could not call SerializeToString on resp object='+str(respb),e) + _logger.exception('jmessage_to_bytes failed. jmessage=%s' % (jmessage)) raise e # If Python 2 we convert the string to bytearray if PY2: - resBytes = bytearray(resBytes) - return resBytes + jmessage_bytes = bytearray(jmessage_bytes) + t1 = time.time() + _timing.debug("protobuf.jmessage_to_bytes;diff="+str(1000*(t1-t0))+"ms") + return jmessage_bytes + +def pmessage_to_jmessage(jmessage_class, pmessage): + if not pmessage: + return None + message_bytes = pmessage_to_bytes(pmessage) + if not message_bytes: + return None + return bytes_to_jmessage(jmessage_class, message_bytes) + +def jmessage_to_pmessage(pmessage_class, jmessage): + if not jmessage: + return None + message_bytes = jmessage_to_bytes(jmessage) + if not message_bytes: + return None + return bytes_to_pmessage(pmessage_class, message_bytes) + def protobuf_remote_service(**kwargs): ''' @@ -232,25 +305,236 @@ def sayHello(self,pbarg): ''' issubclass(arg_type, Message) def pbwrapper(func): + def logged_wrapped_exception(msg): + exc_type, exc_value, exc_traceback = sys.exc_info() + from traceback import format_exception + lines = format_exception(exc_type, exc_value, exc_traceback) + lines[1:2] = [] + _logger.error(msg + ('\n%s' % (''.join(lines)))) + func._arg_type = arg_type func._return_type = return_type + func._source = None + try: + from inspect import getsource + setattr(func, PB_SERVICE_SOURCE_ATTR, getsource(func)) + except: + pass @wraps(func) def wrapper(*args): # set argClass to arg_type argClass = arg_type # signature should be: self,arg. Pass args[1]...the actual argument # ...to deserialize byte[] into pb Message into argInst - argInst = argument_deserialize(argClass, args[1]) + argInst = bytes_to_pmessage(argClass, args[1]) respb = None + t0 = time.time() try: # Now actually call function, with self,pbMessage respb = func(args[0],argInst) except Exception as e: - _logger.error('Could not call function='+str(func)+' on object='+str(args[0])) + logged_wrapped_exception('Remote method invoke failed') raise e + t1 = time.time() + _timing.debug("protobuf.exec;time="+str(1000*(t1-t0))+"ms") if not func._return_type is None: isinstance(respb,func._return_type) - return return_serialize(respb) + return pmessage_to_bytes(respb) return wrapper return pbwrapper +def get_python_return_type(java_return_class): + jdesc_bytes = java_return_class.getMethod("getDescriptor",None).invoke(None,None).toProto().toByteArray() + if PY2: + jdesc_bytes = str(jdesc_bytes) + pdesc_proto = DescriptorProto() + pdesc_proto.MergeFromString(jdesc_bytes) + return MakeClass(MakeDescriptor(pdesc_proto)) + +def get_interface_methods(java_interface_class, proxy): + result_methods = [] + try: + jmethods = java_interface_class.getMethods() + for jmethod in jmethods: + jmethod_name = jmethod.getName() + if (jmethod_name not in JAVA_OBJECT_METHODS): + java_parameter_types = jmethod.getParameterTypes() + java_return_class = jmethod.getReturnType() + python_return_type = get_python_return_type(java_return_class) + result_methods.append(ProtobufServiceMethod(proxy,jmethod_name,java_parameter_types,python_return_type)) + return result_methods + except Exception as e: + _logger.exception('Could not get interface methods from java_interface_class='+str(java_interface_class)) + raise e + +def get_interfaces_methods(jvm, interfaces, proxy): + result = {} + for interface in interfaces: + interface_class = jvm.java.lang.Class.forName(interface) + result[interface] = get_interface_methods(interface_class, proxy) + return result + +class ProtobufServiceMethod(object): + + def __init__(self,proxy,name,java_arg_types,python_return_type): + self._java_proxy = proxy + self._methodname = name + self._java_arg_types = java_arg_types + self._python_return_type = python_return_type + + def __call__(self,*args): + # serialize python message to bytes + pmessage_bytes = pmessage_to_bytes(args[0]) + jmessage = None + if pmessage_bytes: + # convert bytes to java message + jmessage = bytes_to_jmessage(self._java_arg_types[0], pmessage_bytes) + # make remote java call with java message + t0 = time.time() + jresult = None + try: + jresult = getattr(self._java_proxy,self._methodname)(jmessage) + except Exception as e: + _logger.exception("Exception making remote java call to methodname="+self._methodname) + raise e + t1 = time.time() + _timing.debug("protobuf.exec;time="+str(1000*(t1-t0))+"ms") + if not jresult: + return None + # convert java result to bytes + jbytes = jmessage_to_bytes(jresult) + if PY2: + jbytes = str(jbytes) + # convert bytes to python return type + return bytes_to_pmessage(self._python_return_type, jbytes) + +class ProtobufServiceProxy(object): + + def __init__(self, jvm, interfaces, proxy): + self._interfaces = get_interfaces_methods(jvm,interfaces,proxy) + + def _find_java_method(self,name): + for method_list in self._interfaces.values(): + for method in method_list: + if name == method._methodname: + return method + return None + + def __getattr__(self, name): + if name == "__call__": + raise AttributeError + + java_method = self._find_java_method(name) + if not java_method: + raise AttributeError + + return java_method + +class ProtobufServiceRegistry(Py4jServiceBridgeEventListener,JavaRemoteServiceRegistry): + + def __init__(self): + super(ProtobufServiceRegistry, self).__init__() + + def service_imported(self, servicebridge, endpointid, proxy, endpoint_props): + imported_configs = endpoint_props[osgiservicebridge.SERVICE_IMPORTED_CONFIGS] + theproxy = None + if (osgiservicebridge.protobuf.JAVA_HOST_CONFIG_TYPE in imported_configs): + theproxy = ProtobufServiceProxy(servicebridge._gateway.jvm,endpoint_props[osgiservicebridge.OBJECT_CLASS],proxy) + else: + theproxy = proxy + + self._add_remoteservice(endpoint_props, theproxy) + + def service_modified(self, servicebridge, endpointid, proxy, endpoint_props): + self._modify_remoteservice(endpointid, endpoint_props) + + def service_unimported(self, servicebridge, endpointid, proxy, endpoint_props): + self._remove_remoteservice(endpointid) + +import importlib +import inspect + +JAVA_OBJECT_METHODS = [ 'equals', 'hashCode', 'wait', 'notify', 'notifyAll', 'getClass', 'toString'] + +PYTHON_SERVICE_EXPORTER_PACKAGE='org.eclipse.ecf.python.protobuf' +PYTHON_SERVICE_EXPORTER_PACKAGE_VERSION='1.0.0' +PYTHON_SERVICE_EXPORTER=PYTHON_SERVICE_EXPORTER_PACKAGE + '.IPythonServiceExporter' + +@protobuf_remote_service( + objectClass=[PYTHON_SERVICE_EXPORTER],export_properties = { ECF_SERVICE_EXPORTED_ASYNC_INTERFACES: '*', + ENDPOINT_PACKAGE_VERSION_+PYTHON_SERVICE_EXPORTER_PACKAGE: PYTHON_SERVICE_EXPORTER_PACKAGE_VERSION }) +class PythonServiceExporter(object): + + def __init__(self,bridge): + self._bridge = bridge + + def _create_error_export_response(self, message): + result = ExportResponse() + result.message = message + return result + + def _create_success_export_response(self, endpoint_id): + result = ExportResponse() + result.endpoint_id = endpoint_id + return result + + def _load_module(self,module_name): + module_ = self.__class__.__module__ + if not module_name: + return sys.modules['__main__'] + try: + try: + module_ = sys.modules[module_name] + except KeyError: + module_ = importlib.import_module(module_name) + sys.modules[module_name] = module_ + except (ImportError, IOError) as ex: + _logger.exception('Could not load module='+module_name,ex) + return None + return module_ + + def _get_class_from_module(self,module,class_name): + def pred(clazz): + return inspect.isclass(clazz) + moduleclasses = inspect.getmembers(module, pred) + if not moduleclasses: + return None + else: + for t in moduleclasses: + if t[0] == class_name: + return t[1] + return None + + @protobuf_remote_service_method(arg_type=ExportRequest,return_type=ExportResponse) + def createAndExport(self, export_request): + try: + module = self._load_module(export_request.module_name) + if not module: + return self._create_error_export_response('Cannot get module for module_name='+\ + str(export_request.module_name)) + clazz = self._get_class_from_module(module, export_request.class_name) + if not clazz: + return self._create_error_export_response('Cannot get class for class_name='+\ + str(export_request.class_name)) + args = export_request.creation_args + if not args or len(args) <= 0: + inst = clazz() + else: + inst = clazz(args) + export_id = self._bridge.export(inst,export_request.overriding_export_props) + return self._create_success_export_response(export_id) + except Exception as ex: + _logger.exception('Could not create and export with request='+str(export_request)) + return self._create_error_export_response(str(ex)) + + @protobuf_remote_service_method(arg_type=UnexportRequest,return_type=UnexportResponse) + def unexport(self, unexport_request): + endpoint_id = self._bridge.unexport(unexport_request.endpoint_id) + result = UnexportResponse() + result.endpoint_id = endpoint_id + if endpoint_id: + result.success = True + else: + result.success = False + return result + \ No newline at end of file diff --git a/python/osgiservicebridge/build/lib/osgiservicebridge/version.py b/python/osgiservicebridge/build/lib/osgiservicebridge/version.py index 61362fc..9ac3d35 100644 --- a/python/osgiservicebridge/build/lib/osgiservicebridge/version.py +++ b/python/osgiservicebridge/build/lib/osgiservicebridge/version.py @@ -1 +1 @@ -__version__= '1.0.0' \ No newline at end of file +__version__= '1.2.0' \ No newline at end of file diff --git a/python/osgiservicebridge/java/osgiservicebridge-java-bundles-2.5.0.zip b/python/osgiservicebridge/java/osgiservicebridge-java-bundles-2.5.0.zip new file mode 100644 index 0000000..c8efff3 Binary files /dev/null and b/python/osgiservicebridge/java/osgiservicebridge-java-bundles-2.5.0.zip differ diff --git a/python/osgiservicebridge/setup.py b/python/osgiservicebridge/setup.py index 6307c0f..e91b8a4 100644 --- a/python/osgiservicebridge/setup.py +++ b/python/osgiservicebridge/setup.py @@ -22,7 +22,7 @@ VERSION_PATH, "exec")) VERSION = __version__ # noqa -JAVA_FILE='java/osgiservicebridge-java-bundles-2.4.0.zip' +JAVA_FILE='java/osgiservicebridge-java-bundles-2.5.0.zip' setup( name='osgiservicebridge', @@ -53,7 +53,7 @@ # 3 - Alpha # 4 - Beta # 5 - Production/Stable - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', # Indicate who your project is intended for 'Intended Audience :: Developers', diff --git a/python/osgiservicebridge/src/osgiservicebridge/__init__.py b/python/osgiservicebridge/src/osgiservicebridge/__init__.py index 9e56686..6a62158 100644 --- a/python/osgiservicebridge/src/osgiservicebridge/__init__.py +++ b/python/osgiservicebridge/src/osgiservicebridge/__init__.py @@ -1,9 +1,10 @@ ''' -OSGi service bridge +OSGi service bridge Google protocol buffers (protobuf) support :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 - Copyright 2016 Composent, Inc. and others +:version: 1.2.0 + Copyright 2017 Composent, Inc. and others Licensed 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 diff --git a/python/osgiservicebridge/src/osgiservicebridge/bridge.py b/python/osgiservicebridge/src/osgiservicebridge/bridge.py index 6d71d43..7d35059 100644 --- a/python/osgiservicebridge/src/osgiservicebridge/bridge.py +++ b/python/osgiservicebridge/src/osgiservicebridge/bridge.py @@ -1,9 +1,9 @@ ''' -OSGi service bridge Py4j classes +OSGi service bridge Google protocol buffers (protobuf) support :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 -:version: 1.1.0 +:version: 1.2.0 Copyright 2017 Composent, Inc. and others Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. ''' - from osgiservicebridge.version import __version__ as __v__ # Version __version__ = __v__ diff --git a/python/osgiservicebridge/src/osgiservicebridge/flatbuf.py b/python/osgiservicebridge/src/osgiservicebridge/flatbuf.py index e9c1329..5741543 100644 --- a/python/osgiservicebridge/src/osgiservicebridge/flatbuf.py +++ b/python/osgiservicebridge/src/osgiservicebridge/flatbuf.py @@ -1,9 +1,9 @@ ''' -OSGi service bridge Google flatbuffers (flatbuf) support +OSGi service bridge Google protocol buffers (protobuf) support :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 -:version: 1.1.0 +:version: 1.2.0 Copyright 2017 Composent, Inc. and others Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/python/osgiservicebridge/src/osgiservicebridge/protobuf.py b/python/osgiservicebridge/src/osgiservicebridge/protobuf.py index da95958..cb02e3e 100644 --- a/python/osgiservicebridge/src/osgiservicebridge/protobuf.py +++ b/python/osgiservicebridge/src/osgiservicebridge/protobuf.py @@ -3,7 +3,7 @@ :author: Scott Lewis :copyright: Copyright 2016, Composent, Inc. :license: Apache License 2.0 -:version: 1.1.0 +:version: 1.2.0 Copyright 2017 Composent, Inc. and others Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.