protobuf.socketrpc-1.3.2/0000755000175000017500000000000011464617602013462 5ustar janjanprotobuf.socketrpc-1.3.2/LICENSE0000644000175000017500000000203711464555053014472 0ustar janjanCopyright (c) 2010 Shardul Deo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. protobuf.socketrpc-1.3.2/src/0000755000175000017500000000000011464617602014251 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/0000755000175000017500000000000011464617602016111 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/0000755000175000017500000000000011464617602020106 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/server.py0000644000175000017500000002244211464555053021773 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' server.py - RPC server implementation for Google's Protocol Buffers. This package provides classes to handle the server side of an RPC transaction, that implements Shardul Deo's RPC protocol, using Protocol Buffers for the data interchange format. See http://code.google.com/p/protobuf-socket-rpc/ http://code.google.com/p/protobuf/ for more information. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Standard library imports import SocketServer import threading import logging import socket # Third-party imports # Module imports from protobuf.socketrpc import rpc_pb2 as rpc_pb from protobuf.socketrpc.controller import SocketRpcController from protobuf.socketrpc import error class NullHandler(logging.Handler): '''A null logging handler to prevent clients that don't require the logging package from reporting no handlers found.''' def emit(self, record): pass log = logging.getLogger(__name__) log.addHandler(NullHandler()) class Callback(): '''Class to allow execution of client-supplied callbacks.''' def __init__(self): self.invoked = False self.response = None def run(self, response): self.response = response self.invoked = True class SocketHandler(SocketServer.StreamRequestHandler): '''Handler for service requests.''' def __init__(self, request, client_address, server, socket_rpc_server): self.socket_rpc_server = socket_rpc_server SocketServer.StreamRequestHandler.__init__( self, request, client_address, server) def handle(self): '''Entry point for handler functionality.''' log.debug('Got a request') # Parse the incoming request recv = self.rfile.read() # Evaluate and execute the request rpcResponse = self.validateAndExecuteRequest(recv) log.debug("Response to return to client \n %s" % rpcResponse) # Send reply to client self.wfile.write(rpcResponse.SerializeToString()) self.request.shutdown(socket.SHUT_RDWR) def validateAndExecuteRequest(self, input): '''Match a client request to the corresponding service and method on the server, and then call the service.''' # Parse and validate the client's request try: request = self.parseServiceRequest(input) except error.BadRequestDataError, e: return self.handleError(e) # Retrieve the requested service try: service = self.retrieveService(request.service_name) except error.ServiceNotFoundError, e: return self.handleError(e) # Retrieve the requested method try: method = self.retrieveMethod(service, request.method_name) except error.MethodNotFoundError, e: return self.handleError(e) # Retrieve the protocol message try: proto_request = self.retrieveProtoRequest(service, method, request) except error.BadRequestProtoError, e: return self.handleError(e) # Execute the specified method of the service with the requested params try: response = self.callMethod(service, method, proto_request) except error.RpcError, e: return self.handleError(e) return response def parseServiceRequest(self, bytestream_from_client): '''Validate the data stream received from the client.''' # Convert the client request into a PB Request object request = rpc_pb.Request() # Catch anything which isn't a valid PB bytestream try: request.MergeFromString(bytestream_from_client) except Exception, e: raise error.BadRequestDataError("Invalid request from \ client (decodeError): " + str(e)) # Check the request is correctly initialized if not request.IsInitialized(): raise error.BadRequestDataError("Client request is missing \ mandatory fields") log.debug('Request = %s' % request) return request def retrieveService(self, service_name): '''Match the service request to a registered service.''' service = self.socket_rpc_server.serviceMap.get(service_name) if service is None: msg = "Could not find service '%s'" % service_name raise error.ServiceNotFoundError(msg) return service def retrieveMethod(self, service, method_name): '''Match the method request to a method of a registered service.''' method = service.DESCRIPTOR.FindMethodByName(method_name) if method is None: msg = "Could not find method '%s' in service '%s'"\ % (method_name, service.DESCRIPTOR.name) raise error.MethodNotFoundError(msg) return method def retrieveProtoRequest(self, service, method, request): ''' Retrieve the users protocol message from the RPC message''' proto_request = service.GetRequestClass(method)() try: proto_request.ParseFromString(request.request_proto) except Exception, e: raise error.BadRequestProtoError(unicode(e)) # Check the request parsed correctly if not proto_request.IsInitialized(): raise error.BadRequestProtoError('Invalid protocol request \ from client') return proto_request def callMethod(self, service, method, proto_request): '''Execute a service method request.''' log.debug('Calling service %s' % service) log.debug('Calling method %s' % method) # Create the controller (initialised to success) and callback controller = SocketRpcController() callback = Callback() try: service.CallMethod(method, controller, proto_request, callback) except Exception, e: raise error.RpcError(unicode(e)) # Return an RPC response, with payload defined in the callback response = rpc_pb.Response() if callback.response: response.callback = True response.response_proto = callback.response.SerializeToString() else: response.callback = callback.invoked # Check to see if controller has been set to not success by user. if controller.failed(): response.error = controller.error() response.error_reason = rpc_pb.RPC_FAILED return response def handleError(self, e): '''Produce an RPC response to convey a server error to the client.''' msg = "%d : %s" % (e.rpc_error_code, e.message) log.error(msg) # Create error reply response = rpc_pb.Response() response.error_reason = e.rpc_error_code response.error = e.message return response class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): SocketServer.allow_reuse_address = True def __init__(self, server_address, RequestHandlerClass, socket_rpc_server): """Constructor. May be extended, do not override.""" SocketServer.TCPServer.__init__( self, server_address, RequestHandlerClass) self.socket_rpc_server = socket_rpc_server def finish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass( request, client_address, self, self.socket_rpc_server) class SocketRpcServer: '''Socket server for running rpc services.''' def __init__(self, port, host='localhost'): '''port - Port this server is started on''' self.port = port self.host = host self.serviceMap = {} def registerService(self, service): '''Register an RPC service.''' self.serviceMap[service.GetDescriptor().full_name] = service def run(self): '''Activate the server.''' log.info('Running server on port %d' % self.port) server = ThreadedTCPServer((self.host, self.port), SocketHandler, self) server.serve_forever() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/service.py0000644000175000017500000002030511464555053022121 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' service.py - A wrapper around protocol buffer rpc services. Allows protocol buffer rpc services to be called directly by method name either synchronously or asynchronously without having to worry about the setup details. RpcService is a class that constructs a service instance from a service stub in a protoc generated pb2 module. RpcThread is a simple thread handling the RPC call outside of the main thread. Authors: Zach Walker (zwalker@lcogt.net) Jan Dittberner (jan@dittberner.info) Nov 2009, Nov 2010 ''' # Standard library imports from time import time import threading # Third party imports from protobuf.socketrpc.channel import SocketRpcChannel from protobuf.socketrpc.error import RpcError # Module imports from protobuf.socketrpc import logger log = logger.getLogger(__name__) class RpcThread(threading.Thread): ''' Thread for handling an rpc request ''' def __init__(self, method, service, controller, request, callback): threading.Thread.__init__(self) self.method = method self.service = service self.controller = controller self.request = request self.callback = callback self.setDaemon(True) def run(self): # Make the RPC call and pass in a object with a # function called "run" if callable(self.callback): # Attempting to do something similar to a JAVA anonymous class # Create an instance of a new generic type initialized with a # dict that has a run method pointing to the callback function self.method(self.service, self.controller, self.request, type("", (), {"run": lambda *args: \ self.callback(self.request, args[1])})()) else: # Assuming callback has a run method self.method(self.service, self.controller, self.request, self.callback) class RpcService(object): ''' Class abstracting the Protocol Buffer RPC calls for a supplied service stub. ''' def __init__(self, service_stub_class, port, host): ''' Contruct a new ProtoBufRpcRequest and return it. Accepted Arguments: service_stub_class -- (Service_Stub) The client side RPC stub class produced by protoc from the .proto file port -- (Integer) The port on which the service is running on the RPC server. host -- (String) The hostname or IP address of the server running the RPC service. ''' self.service_stub_class = service_stub_class self.port = port self.host = host # Setup the RPC channel self.channel = SocketRpcChannel(host=self.host, port=self.port) self.service = self.service_stub_class(self.channel) # go through service_stub methods and add a wrapper function to # this object that will call the method for method in service_stub_class.GetDescriptor().methods: # Add service methods to the this object rpc = lambda request, timeout=None, callback=None, service=self, \ method=method.name: \ service.call(service_stub_class.__dict__[method], request, timeout, callback) rpc.__doc__ = method.name + ' method of the ' + \ service_stub_class.DESCRIPTOR.name + ' from the ' + \ service_stub_class.__module__ + ' module generated by the ' + \ 'protoc compiler. This method can be called ' + \ 'synchronously by setting timeout -> ms or ' + \ 'asynchrounously by setting callback -> ' + \ 'function(request,response)\n\nSynchronous Example:\n' + \ '\trequest = ' + method.input_type.name + '()\n' + \ '\ttry:\n' + \ '\t#Wait 1000ms for a response\n' + \ '\t\tresponse = ' + method.name + \ '(request, timeout=1000)\n' + \ '\texcept: RpcException\n' + \ '\t\t#Handle exception\n\n' + \ 'Asynchronous Example:\n' + \ '\tdef callback(request,response):\n' + \ '\t\t#Do some stuff\n' + \ '\trequest = ' + method.input_type.name + '()\n' + \ '\ttry:\n' + \ '\t\t' + method.name + '(request, callback=callback)\n' + \ '\texcept: RpcException\n' + \ '\t\t#Handle exception\n\n' self.__dict__[method.name] = rpc def call(self, rpc, request, timeout=None, callback=None): ''' Save the object that has been created and return the response. Will timeout after timeout ms if response has not been received. The timeout arg is only used for asynch requests. If a callback has been supplied the timeout arg is not used. The response value will be returned for a synch request but nothing will be returned for an asynch request. Accepted Arguments: timeout -- (Integer) ms to wait for a response before returning ''' # Define local callback function to handle RPC response # and initialize result dict result = {'done': False, 'response': None} def synch_callback(request, response): result['response'] = response result['done'] = True result['error_msg'] = '' result['success'] = True # If no callback has been passed in then this is meant to be # synchronous if callback == None: rpc_callback = synch_callback else: if ((not callable(callback) and (callback.__class__.__dict__.get('run') == None or callback.run.func_code.co_argcount < 2)) or (callable(callback) and callback.func_code.co_argcount < 2)): raise Exception("callback must be a callable with signature " + "callback(request, response, ...) or an " + "object with a callable run function with " + "the same signature") rpc_callback = callback # Create a controller for this call controller = self.channel.newController() # Spawn a new thread to wait for the callback so this can return # immediately if an asynch callback has been requested rpc_thread = RpcThread(rpc, self.service, controller, request, rpc_callback) rpc_thread.start() # If a callback has been passed in return if rpc_callback == callback: return else: if timeout == None: timeout = 100 end = time() + (timeout / 1000) # Wait for timeout or thread to exit indicating call has returned rpc_thread.join(timeout) if time() >= end and not result['done']: raise RpcError('request timed out') return result['response'] protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/0000755000175000017500000000000011464617602021250 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/controller_test.py0000644000175000017500000001076111464555053025052 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' controller_test.py - unit tests for the protobuf.controller module. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Zach Walker (zwalker@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Standard library imports import unittest # Add protobuf module to the classpath import sys sys.path.append('../../main') # Import the class to test import protobuf.socketrpc.controller as controller # Import the fake stub classes used in testing to simulate sockets etc. from fake import FakeSocketFactory, FakeSocket, FakeCallback, TestServiceImpl # Import the RPC definition class and the test service class import protobuf.socketrpc.rpc_pb2 as rpc_pb2 import test_pb2 class TestSocketRpcController(unittest.TestCase): '''Unit tests for the protobuf.channel.SocketRpcController class.''' def setUp(self): self.controller = controller.SocketRpcController() def tearDown(self): pass def test___init__(self): '''Test SocketRpcController constructor.''' self.assertEqual(self.controller._fail, False, "Attribute 'fail' incorrectly initialized") self.assertEqual(self.controller._error, None, "Attribute 'error' incorrectly initialized") self.assertEqual(self.controller.reason, None, "Attribute 'reason' incorrectly initialized") def test_handleError(self): '''Test handleError - normal usage.''' # Set the controller state to see if it is changed correctly self.controller._fail = False # Create an error code and message to pass in error_code = '4' message = 'Chips are soggy' self.controller.handleError(error_code, message) self.assertEqual(self.controller._fail, True, "handleError - Attribute 'success'") self.assertEqual(self.controller.reason, error_code, "handleError - Attribute 'reason'") self.assertEqual(self.controller._error, message, "handleError - Attribute 'error'") def test_reset(self): '''Test reset - normal usage.''' # Set the controller state to see if it is changed correctly self.controller._fail = True self.controller.reason = '4' self.controller._error = 'Chips are soggy' self.controller.reset() self.assertEqual(self.controller._fail, False, "reset - Attribute 'fail'") self.assertEqual(self.controller._error, None, "reset - Attribute 'error'") self.assertEqual(self.controller.reason, None, "reset - Attribute 'reason'") def test_failed(self): '''Test failed - normal usage.''' self.controller._fail = False self.assertEqual(self.controller.failed(), False, "failed - no failure state") self.controller._fail = True self.assertEqual(self.controller.failed(), True, "failed - failure state") def suite(): '''Return the test suite containing all tests from this module.''' suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestSocketRpcController)) return suite if __name__ == '__main__': unittest.main() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/error_test.py0000644000175000017500000001335611464555052024022 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' error_test.py - unit tests for the protobuf.error module. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Modify path to include protobuf import sys sys.path.append('../../main') # Standard library imports import unittest # Import the class to test import protobuf.socketrpc.error as error # Module imports import protobuf.socketrpc.rpc_pb2 as rpc_pb2 class TestServerError(unittest.TestCase): '''Unit tests for the protobuf.server.ServerError subclasses.''' def setUp(self): self.msg = 'This is an error message.' def tearDown(self): pass def test_ProtobufError(self): expected_error_code = 1 e = error.ProtobufError(self.msg, expected_error_code) self.assertEqual(e.message, self.msg, 'ProtobufError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'ProtobufError - error code') def test_BadRequestDataError(self): expected_error_code = rpc_pb2.BAD_REQUEST_DATA e = error.BadRequestDataError(self.msg) self.assertEqual(e.message, self.msg, 'BadRequestDataError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'BadRequestDataError - error code') def test_BadRequestProtoError(self): expected_error_code = rpc_pb2.BAD_REQUEST_PROTO e = error.BadRequestProtoError(self.msg) self.assertEqual(e.message, self.msg, 'BadRequestProtoError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'BadRequestProtoError - error code') def test_ServiceNotFoundError(self): expected_error_code = rpc_pb2.SERVICE_NOT_FOUND e = error.ServiceNotFoundError(self.msg) self.assertEqual(e.message, self.msg, 'ServiceNotFoundError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'ServiceNotFoundError - error code') def test_MethodNotFoundError(self): expected_error_code = rpc_pb2.METHOD_NOT_FOUND e = error.MethodNotFoundError(self.msg) self.assertEqual(e.message, self.msg, 'MethodNotFoundError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'MethodNotFoundError - error code') def test_RpcError(self): expected_error_code = rpc_pb2.RPC_ERROR e = error.RpcError(self.msg) self.assertEqual(e.message, self.msg, 'RpcError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'RpcError - error code') def test_RpcFailed(self): expected_error_code = rpc_pb2.RPC_FAILED e = error.RpcFailed(self.msg) self.assertEqual(e.message, self.msg, 'RpcFailed - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'RpcFailed - error code') def test_InvalidRequestProtoError(self): expected_error_code = rpc_pb2.INVALID_REQUEST_PROTO e = error.InvalidRequestProtoError(self.msg) self.assertEqual(e.message, self.msg, 'InvalidRequestProtoError - \ message') self.assertEqual(e.rpc_error_code, expected_error_code, 'InvalidRequestProtoError - error code') def test_BadResponseProtoError(self): expected_error_code = rpc_pb2.BAD_RESPONSE_PROTO e = error.BadResponseProtoError(self.msg) self.assertEqual( e.message, self.msg, 'BadResponseProtoError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'BadResponseProtoError - error code') def test_UnknownHostError(self): expected_error_code = rpc_pb2.UNKNOWN_HOST e = error.UnknownHostError(self.msg) self.assertEqual(e.message, self.msg, 'UnknownHostError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'UnknownHostError - error code') def test_IOError(self): expected_error_code = rpc_pb2.IO_ERROR e = error.IOError(self.msg) self.assertEqual(e.message, self.msg, 'IOError - message') self.assertEqual(e.rpc_error_code, expected_error_code, 'IOError - error code') def suite(): '''Return the test suite containing all tests from this module.''' suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestServerError)) return suite if __name__ == '__main__': unittest.main() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/server_test.py0000644000175000017500000004617311464555053024203 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' test_server_protobuf.py - unit tests for the protobuf.server module. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Modify path to make the script executable. import sys sys.path.append('../../main') # Standard library imports import unittest # Third-party imports from google.protobuf.message import DecodeError # Module imports import protobuf.socketrpc.server as server import protobuf.socketrpc.rpc_pb2 as rpc_pb2 import protobuf.socketrpc.error as error # Test imports (relative imports) from fake import FakeSocketFactory, TestServiceImpl import test_pb2 class TestCallback(unittest.TestCase): '''Unit tests for the protobuf.server.Callback class.''' def setUp(self): self.c = server.Callback() def tearDown(self): pass def test___init__1(self): self.assertEqual(self.c.invoked, False, "Attribute 'invoked' incorrectly initialized") def test___init__2(self): self.assertEqual(self.c.response, None, "Attribute 'response' incorrectly initialized") def test_run1(self): response = 'ack' self.c.run(response) self.assertEqual(self.c.response, response, "Attribute 'response' incorrectly updated") def test_run2(self): response = 'ack' self.c.run(response) self.assertEqual(self.c.invoked, True, "Attribute 'invoked' incorrectly updated") class TestSocketHandler(unittest.TestCase): '''Unit tests for the protobuf.server.SocketHandler class.''' def setUp(self): # Define some arbitrary values to satisfy the interface self.client_addr = 'here' self.server_addr = 'there' # Define a simple service request self.service_request = test_pb2.Request() self.service_request.str_data = 'The lord giveth' self.serialized_request = self.service_request.SerializeToString() # Define an RPC request with the service request as payload self.rpc_request = rpc_pb2.Request() self.rpc_request.request_proto = self.serialized_request self.testserver = server.SocketRpcServer(8090) def tearDown(self): pass def serializeRpcRequestToSocket(self, partial=False): '''Convenience function for preparing socket connection tests.''' # Don't validate the RPC request if the partial flag is provided if partial: bytestream = self.rpc_request.SerializePartialToString() else: bytestream = self.rpc_request.SerializeToString() socket_factory = FakeSocketFactory() socket = socket_factory.createSocket() return (bytestream, socket) def registerTestService(self, exception=None, failmsg=None): '''Convenience function to set up a test service.''' # Set up a simple test service service = TestServiceImpl(exception, failmsg) self.testserver.registerService(service) return service def test_callMethod(self): ''' Test normal return for callMethod ''' # Get the service and method service = self.registerTestService() method = service.DESCRIPTOR.FindMethodByName("TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() # Construct the expected response from the service expected_response = test_pb2.Response() expected_response.str_data = service.response_str_data expected_response.int_data = service.response_int_data serialized_payload = expected_response.SerializeToString() # Wrap the expected response in an RPC Response message expected_rpc = rpc_pb2.Response() expected_rpc.callback = True expected_rpc.response_proto = serialized_payload handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) response = handler.callMethod(service, method, self.service_request) self.assertEquals(response, expected_rpc, 'Normal response') def test_callMethod_RPC_FAILED(self): '''Test for RPCFAILED state.''' # Get the service and method failmsg = "User defined error" service = self.registerTestService(None, failmsg) method = service.DESCRIPTOR.FindMethodByName("TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) response = handler.callMethod(service, method, self.service_request) self.assertEquals(response.error_reason, rpc_pb2.RPC_FAILED, 'RPC_FAILED - error code') self.assertEquals(response.error, failmsg, 'RPC_FAILED - messsage') def test_callMethod_RPC_ERROR(self): '''Test for RPCERROR state.''' # Get the service and method exception = Exception('An exception has been raised') service = self.registerTestService(exception) method = service.DESCRIPTOR.FindMethodByName("TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) self.assertRaises( error.RpcError, handler.callMethod, service, method, self.service_request) def test_parseServiceRequest(self): '''Test normal return from parseServiceRequest.''' # Define the required fields of the RPC request self.rpc_request.service_name = 'service_full_name' self.rpc_request.method_name = 'method_name' # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) self.assertEqual(handler.parseServiceRequest(bytestream), self.rpc_request, "Parsing request - normal return") def test_parseServiceRequest_BAD_REQUEST_DATA(self): ''' Test the correct error is raised after sending an invalid request. ''' # Define an invalid RPC request (missing required service name) self.rpc_request.method_name = 'method_name' # Serialize the request (without checking initialisation status) (bytestream, sock) = self.serializeRpcRequestToSocket(partial=True) # Test the server handler raises the BAD_REQUEST_DATA error code handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) self.assertRaises(error.BadRequestDataError, handler.parseServiceRequest, bytestream) def test_parseServiceRequest_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Bind an arbitrary bytestream to the socket bytestream = 'ABCD' socket_factory = FakeSocketFactory() sock = socket_factory.createSocket() # Test the server handler raises the BAD_REQUEST_DATA error code handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) self.assertRaises(error.BadRequestDataError, handler.parseServiceRequest, bytestream) def test_retrieveService(self): '''Test normal return from retrieveService.''' # Add a test service expected_service = self.registerTestService() # Define an RPC request for an existing service and method self.rpc_request.service_name = expected_service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) # Run the method on the server received_service = handler.retrieveService( self.rpc_request.service_name) self.assertEqual(received_service, expected_service, 'Service found') def test_retrieveService_SERVICE_NOT_FOUND(self): '''Test exceptional return from retrieveService.''' # Add a test service expected_service = self.registerTestService() # Define an RPC request for a non-existent service and method self.rpc_request.service_name = "Non-existent service" self.rpc_request.method_name = "Dummy method" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) # Run the method on the server self.assertRaises(error.ServiceNotFoundError, handler.retrieveService, self.rpc_request.service_name) def test_retrieveMethod(self): '''Test normal return from retrieveMethod.''' # Add a test service expected_service = self.registerTestService() expected_method = expected_service.DESCRIPTOR.FindMethodByName( "TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = expected_service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) # Run the method on the server received_method = handler.retrieveMethod(expected_service, self.rpc_request.method_name) self.assertEqual(received_method, expected_method, 'Method found') def test_retrieveMethod_METHOD_NOT_FOUND(self): '''Test exceptional return from retrieveMethod.''' # Add a test service expected_service = self.registerTestService() expected_method = expected_service.DESCRIPTOR.FindMethodByName( "TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = expected_service.DESCRIPTOR.full_name self.rpc_request.method_name = "Non-existent method" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) # Run the method on the server self.assertRaises(error.MethodNotFoundError, handler.retrieveMethod, expected_service, self.rpc_request.method_name) def test_retrieveProtoRequest(self): '''Test normal return from retrieveMethod.''' # Protocol message expected_str_data = self.service_request.str_data # Add a test service expected_service = self.registerTestService() expected_method = expected_service.DESCRIPTOR.FindMethodByName( "TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = expected_service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) proto_request = handler.retrieveProtoRequest( expected_service, expected_method, self.rpc_request) self.assertEqual(proto_request.str_data, expected_str_data, 'Normal response') def test_retrieveProtoRequest_BAD_REQUEST_PROTO(self): '''Test exceptional return from retrieveProtoRequest.''' # Protocol message expected_str_data = self.service_request.str_data # Add a test service expected_service = self.registerTestService() expected_method = expected_service.DESCRIPTOR.FindMethodByName( "TestMethod") # Define an RPC request for an existing service and method self.rpc_request.service_name = expected_service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request and create the socket handler (bytestream, sock) = self.serializeRpcRequestToSocket() handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) # Force a bad protocol message self.rpc_request.request_proto = "Bad protocol message" # Run the method self.assertRaises(error.BadRequestProtoError, handler.retrieveProtoRequest, expected_service, expected_method, self.rpc_request) def test_validateAndExecuteRequest(self): '''Test a request for an existing service and method.''' # Add a test service service = self.registerTestService() # Define an RPC request for an existing service and method self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = "TestMethod" # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() # Construct the expected response from the service expected_response = test_pb2.Response() expected_response.str_data = service.response_str_data expected_response.int_data = service.response_int_data serialized_payload = expected_response.SerializeToString() expected_rpc = rpc_pb2.Response() expected_rpc.callback = True expected_rpc.response_proto = serialized_payload # Run the method on the server handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) received_rpc = handler.validateAndExecuteRequest(bytestream) # Check the response message error code self.assertEqual(received_rpc, expected_rpc, 'Normal response') def test_validateAndExecuteRequest_SERVICE_NOT_FOUND(self): '''Test a request for a non-existent service.''' # Define an RPC request for a non-existent service self.rpc_request.service_name = "Non-existent service" self.rpc_request.method_name = "Dummy method" # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() # Run the method on the server handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) response = handler.validateAndExecuteRequest(bytestream) # Check the response message error code self.assertEqual(response.error_reason, rpc_pb2.SERVICE_NOT_FOUND, 'Unexpected error code') def test_validateAndExecuteRequest_METHOD_NOT_FOUND(self): '''Test a request for a non-existent method.''' # Add a test service service = self.registerTestService() # Define an RPC request for an existing service but non-existent method self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = 'Dummy method' # Serialize the request (bytestream, sock) = self.serializeRpcRequestToSocket() # Run the method on the server handler = server.SocketHandler(sock, self.client_addr, self.server_addr, self.testserver) response = handler.validateAndExecuteRequest(bytestream) # Check the response message error code self.assertEqual(response.error_reason, rpc_pb2.METHOD_NOT_FOUND, 'Unexpected error code') class TestSocketRpcServer(unittest.TestCase): '''Unit tests for the protobuf.server.SocketRpcServer class.''' def setUp(self): self.port = 8090 self.server = server.SocketRpcServer(self.port) def tearDown(self): pass def test___init__(self): self.assertEqual(self.server.port, self.port, "Attribute 'port' incorrectly initialized") def test_register_service(self): self.service = TestServiceImpl() self.server.registerService(self.service) self.map = {'protobuf.socketrpc.TestService': self.service} self.assertEqual(self.server.serviceMap, self.map, "Adding service to internal map") def suite(): '''Return the test suite containing all tests from this module.''' suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestCallback)) suite.addTest(unittest.makeSuite(TestSocketHandler)) suite.addTest(unittest.makeSuite(TestSocketRpcServer)) return suite if __name__ == '__main__': unittest.main() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/service_test.py0000644000175000017500000002404711464555052024330 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' service_test.py - unit tests for the protobuf.service module. Authors: Zach Walker (zwalker@lcogt.net) Jan Dittberner (jan@dittberner.info) Nov 2009, Nov 2010 ''' # Standard library imports import unittest import sys import threading from time import sleep # Add protobuf module to path sys.path.append('../../main') # Import the class to test import protobuf.socketrpc.service as service from protobuf.socketrpc.error import RpcError from protobuf.socketrpc.channel import SocketRpcChannel import protobuf.socketrpc.server as server import fake # Import the protoc generated test module import protobuf.socketrpc.rpc_pb2 as rpc_pb2 import test_pb2 success_port = 63636 fail_port = 63637 host = 'localhost' class ServerThread(threading.Thread): '''Singleton class for starting a server thread''' # Singleton instance success_instance = None fail_instance = None def __init__(self, port, exception=None): threading.Thread.__init__(self) if exception is None: self.test_service = fake.TestServiceImpl() else: self.test_service = fake.TestServiceImpl(exception=exception) self.server = server.SocketRpcServer(port) self.server.registerService(self.test_service) self.setDaemon(True) @staticmethod def start_server(success_port, fail_port, exception): '''Start the singleton instance if not already running Will not exit until the process ends ''' if ServerThread.success_instance == None: ServerThread.success_instance = ServerThread(success_port, None) ServerThread.success_instance.start() if ServerThread.fail_instance == None: ServerThread.fail_instance = ServerThread(fail_port, exception) ServerThread.fail_instance.start() def run(self): self.server.run() class Callback(object): '''A simple call back object for testing RpcService callbacks''' def __init__(self): self.called = False self.response = None self.condition = threading.Condition(threading.Lock()) def run(self, response): self.condition.acquire() self.called = True self.response = response self.condition.notify() self.condition.release() class TestRpcService(unittest.TestCase): '''Unit tests for the protobuf.service.RpcService class.''' # For testing asynch callback as a method callback_method_called = False callback_method_request = None callback_method_response = None callback_method_condition = threading.Condition() # Asynch callback method for testing @staticmethod def callback(request, response): TestRpcService.callback_method_condition.acquire() TestRpcService.callback_method_called = True TestRpcService.callback_method_request = request TestRpcService.callback_method_response = response TestRpcService.callback_method_condition.notify() TestRpcService.callback_method_condition.release() def setUp(self): self.service = service.RpcService(test_pb2.TestService_Stub, success_port, host) self.fail_service = service.RpcService(test_pb2.TestService_Stub, fail_port, host) self.request = test_pb2.Request() self.request.str_data = 'I like cheese' # Start a server thread ServerThread.start_server( success_port, fail_port, Exception('YOU FAIL!')) def tearDown(self): pass def test__init__(self): '''Test RpcService constructor.''' self.assertEqual(self.service.service_stub_class, test_pb2.TestService_Stub, "Attribute 'port' incorrectly initialized") self.assertEqual(self.service.port, success_port, "Attribute 'port' incorrectly initialized") self.assertEqual(self.service.host, host, "Attribute 'host' incorrectly initialized") for method in self.service.service_stub_class.GetDescriptor().methods: self.assertNotEqual(self.service.__dict__.get(method.name), None, "method %s not found in service" % method.name) def test_call_asynch_callback_object(self): '''Test an asynchronous callback object''' callback = Callback() callback.condition.acquire() try: self.service.TestMethod(self.request, callback=callback) except Exception, e: self.assert_(False, 'Caught an unexpected exception %s' % e) callback.condition.wait(2.0) self.assertEquals(True, callback.called, 'Asynch callback was not called') # Cannot compare response to None because of bug in protobuf # msg compare code self.assert_( type(callback.response) != None.__class__, 'Callback response was None') def test_call_asynch_callback_method(self): '''Test an asynchronous callback method''' TestRpcService.callback_method_condition.acquire() try: self.service.TestMethod( self.request, callback=TestRpcService.callback) except Exception, e: self.fail('Caught an unexpected exception %s' % e) TestRpcService.callback_method_condition.wait(2.0) self.assertEquals( True, TestRpcService.callback_method_called, 'Asynch callback was not called') self.assertEquals( self.request, TestRpcService.callback_method_request, 'Asynch callback request arg not equal to request') # Cannot compare reponse to None because of bug in protobuf # msg compare code self.assert_( type(TestRpcService.callback_method_response) != None.__class__, 'Callback response was None') def test_call_synch(self): '''Test a synchronous call''' try: response = self.service.TestMethod(self.request, timeout=1000) except Exception, e: self.fail('Caught an unexpected exception %s' % e) self.assertNotEqual(type(response) != None.__class__, 'Callback response was None') def test_call_synch_fail(self): '''Test a synchronous call''' self.assertRaises( Exception, self.fail_service.TestMethod, (self.request), {'timeout': 1000}) try: reponse = self.fail_service.TestMethod(self.request, timeout=1000) except Exception, e: self.assertEqual(e.message, "YOU FAIL!") class TestRpcThread(unittest.TestCase): ''' Unit tests for the protobuf.service.RpcThread class.''' def setUp(self): self.channel = SocketRpcChannel(host=host, port=success_port) self.controller = self.channel.newController() self.service = test_pb2.TestService_Stub(self.channel) self.request = test_pb2.Request() self.request.str_data = 'I like cheese' self.callback = lambda request, response: response self.thread = service.RpcThread( test_pb2.TestService_Stub.TestMethod, self.service, self.controller, self.request, self.callback) ServerThread.start_server( success_port, fail_port, Exception('YOU FAIL!')) def tearDown(self): pass def test__init__(self): '''Test RpcThread constructor.''' self.assertEqual(self.thread.method, test_pb2.TestService_Stub.TestMethod, "Attribute 'method' incorrectly initialized") self.assertEqual(self.thread.service, self.service, "Attribute 'service' incorrectly initialized") self.assertEqual(self.thread.controller, self.controller, "Attribute 'controller' incorrectly initialized") self.assertEqual(self.thread.request, self.request, "Attribute 'request' incorrectly initialized") self.assertEqual(self.thread.callback, self.callback, "Attribute 'callback' incorrectly initialized") self.assertEqual(self.thread.isDaemon(), True, "Thread not set as Daemon") def test_run(self): '''Test the run method''' try: self.thread.run() except Exception, e: self.assert_(False, "TestRpcThread.run() threw and exception", e) def suite(): '''Returns a test suite containing all module tests''' suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestRpcService)) suite.addTest(unittest.makeSuite(TestRpcThread)) return suite if __name__ == '__main__': unittest.main() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/__init__.py0000644000175000017500000000216011464555052023360 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/channel_test.py0000644000175000017500000006000111464555053024267 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' channel_test.py - unit tests for the protobuf.channel module Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' import unittest # Add protobuf module to the classpath import sys sys.path.append('../../main') # Import the class to test import protobuf.socketrpc.channel as ch import protobuf.socketrpc.error as error # Import the fake stub classes used in testing to simulate sockets etc. from fake import FakeSocketFactory, FakeSocket, FakeCallback, TestServiceImpl # Import the RPC definition class and the test service class import protobuf.socketrpc.rpc_pb2 as rpc_pb2 import test_pb2 class TestSocketRpcChannel(unittest.TestCase): '''Unit tests for the protobuf.channel.SocketRpcChannel class.''' def setUp(self): # Create a channel connected to a fake socket self.factory = FakeSocketFactory() self.channel = ch.SocketRpcChannel(socketFactory=self.factory) # Define a simple service request self.service_request = test_pb2.Request() self.service_request.str_data = 'The lord giveth' self.serialized_request = self.service_request.SerializeToString() # Define a service response self.service_response = test_pb2.Response() self.service_response.str_data = 'And the lord taketh away' self.serialized_response = \ self.service_response.SerializePartialToString() # Define an RPC request with the service request as payload self.rpc_request = rpc_pb2.Request() self.rpc_request.request_proto = self.serialized_request def tearDown(self): pass def test___init__1(self): self.assertEqual(self.channel.sockFactory, self.factory, 'Initialising channel with user-supplied factory') def test___init__defaults(self): self.assert_(self.channel.host, True) self.assert_(self.channel.port, True) def test_validateRequest(self): self.rpc_request.service_name = "Dummy Service" self.rpc_request.method_name = "Dummy Method" self.assertEqual(self.channel.validateRequest(self.rpc_request), None, 'validateRequest - valid request provided') def test_validateRequest_BAD_REQUEST_PROTO(self): # A request with mandatory fields missing self.rpc_request = rpc_pb2.Request() self.assertRaises(error.BadRequestProtoError, self.channel.validateRequest, self.rpc_request) def test_openSocket(self): '''Test normal return from openSocket.''' self.assert_(self.channel.openSocket, "openSocket returns something") def test_openSocket_IO_ERROR(self): '''Test exceptional return from openSocket (IO_ERROR).''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() self.factory.setSocket(socket) self.assertRaises(error.IOError, self.channel.openSocket, 'host', -1) def test_openSocket_UNKNOWN_HOST(self): '''Test exceptional return from openSocket (UNKNOWN_HOST).''' self.assert_(self.channel.openSocket, "openSocket returns something") # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() self.factory.setSocket(socket) self.assertRaises(error.UnknownHostError, self.channel.openSocket, 'host', -1) def test_createRpcRequest(self): '''Test createRpcRequest - normal usage.''' # Instantiate the test service, and get a reference to the method method_name = 'TestMethod' service = TestServiceImpl() method = service.DESCRIPTOR.FindMethodByName(method_name) # Define a simple service request service_request = test_pb2.Request() service_request.str_data = 'The lord giveth' serialized_request = service_request.SerializeToString() # Define an RPC request with the service request as payload expected_rpc = rpc_pb2.Request() expected_rpc.request_proto = serialized_request expected_rpc.service_name = service.DESCRIPTOR.full_name expected_rpc.method_name = method_name self.assertEqual( self.channel.createRpcRequest(method, service_request), expected_rpc, 'createRpcRequest - normal usage') def test_sendRpcMessage(self): '''Test sendRpcMessage - normal usage.''' # Create a socket and service request sock = self.factory.createSocket() sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" # Call the method self.channel.sendRpcMessage(sock, sent_request) # Extract the output that was written to the socket received_request = rpc_pb2.Request() received_request.MergeFromString(sock.output_stream.stream_data) self.assertEqual(received_request, sent_request, 'Request written to socket') def test_sendRpcMessage_IOError(self): '''Test sendRpcMessage - IOError.''' # Create a socket with an IOError condition set sock = self.factory.createSocket() sock.throwIOErrorException() # Create a service request sent_request = self.rpc_request sent_request.service_name = "Dummy service" sent_request.method_name = "Dummy method" self.assertRaises(error.IOError, self.channel.sendRpcMessage, sock, sent_request) def test_recvRpcMessage(self): '''Test recvRpcMessage - normal usage.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) # Call the method self.assertEqual(self.channel.recvRpcMessage(sock), msg, 'recvRpcMessage - normal usage') def test_recvRpcMessage_ioerror(self): '''Test recvRpcMessage - IOError.''' # Create a socket and service request msg = 'Message from server' sock = self.factory.createSocket() sock.withInputBytes(msg) sock.throwIOErrorException() # Call the method self.assertRaises(error.IOError, self.channel.recvRpcMessage, sock) def test_parseResponse(self): '''Test parseResponse - normal usage.''' resp_class = rpc_pb2.Response expected_response = resp_class() bytestream = expected_response.SerializeToString() self.assertEqual(self.channel.parseResponse(bytestream, resp_class), expected_response, 'parseResponse - normal usage') def test_parseResponse_junk_input(self): '''Test the correct error is raised after sending complete crap.''' # Setup an arbitrary and broken bytestream bytestream = 'ABCD' resp_class = rpc_pb2.Response self.assertRaises(error.BadResponseProtoError, self.channel.parseResponse, bytestream, resp_class) def testGoodRpc(self): '''Test a good RPC call.''' # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertTrue(callback.invoked, 'Callback invoked') self.assertEquals(self.service_response.str_data, callback.response.str_data, 'Response message') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name, 'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name, 'Method name') def testUnknownHostException(self): '''Test unknown host.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwUnknownHostException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertFalse(callback.invoked, 'Callback invoked') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.UNKNOWN_HOST, controller.reason, 'Error reason') def testIOErrorWhileCreatingSocket(self): '''Test Error while creating socket.''' # Fake socket primed to throw an unknown host exception socket = FakeSocket() socket.throwIOErrorException() socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertFalse(callback.invoked, 'Callback invoked') self.assertTrue(controller.failed()) self.assertEquals(rpc_pb2.IO_ERROR, controller.reason, 'Error reason') def testIncompleteRequest(self): '''Test calling RPC with incomplete request.''' # Create data service_request = test_pb2.Request() # Fake socket with prepared response socket = FakeSocket() socket.withResponseProto(self.service_response) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, service_request, callback) self.assertFalse(callback.invoked, 'Callback invoked') self.assertEquals(rpc_pb2.BAD_REQUEST_PROTO, controller.reason) self.assertTrue(controller.failed()) def testNoCallBack(self): '''Test RPC failing to invoke callback.''' # Fake socket with callback set to false socket = FakeSocket() socket.withNoResponse(False) socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) self.assertFalse(callback.invoked, 'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertEquals(service.DESCRIPTOR.full_name, socket.getRequest().service_name, 'Service name') self.assertEquals(service.DESCRIPTOR.methods[0].name, socket.getRequest().method_name, 'Method name') def testBadResponse(self): '''Test bad response from server.''' # Fake socket with prepared response socket = FakeSocket() socket.withInputBytes("bad response") socketFactory = FakeSocketFactory() socketFactory.setSocket(socket) # Create channel channel = ch.SocketRpcChannel("host", -1, socketFactory) controller = channel.newController() # Create the service service = test_pb2.TestService_Stub(channel) # Call RPC method callback = FakeCallback() service.TestMethod(controller, self.service_request, callback) # Verify request was sent and bad response received self.assertFalse(callback.invoked, 'Callback invoked') self.assertEquals(self.serialized_request, socket.getRequest().request_proto, 'Request protocol serialisation') self.assertTrue(controller.failed(), 'Controller failed') self.assertEquals(rpc_pb2.BAD_RESPONSE_PROTO, controller.reason, 'Controller reason') class Test__LifeCycle(unittest.TestCase): '''Unit tests for the protobuf.channel._Lifecycle class.''' def setUp(self): # Create a channel connected to a fake socket self.factory = FakeSocketFactory() self.socket = FakeSocket() self.channel = ch.SocketRpcChannel(socketFactory=self.factory) self.controller = self.channel.newController() self.lc = ch._LifeCycle(self.controller, self.channel) self.factory.setSocket(self.socket) # Define a simple service request self.service_request = test_pb2.Request() self.service_request.str_data = 'The lord giveth' self.serialized_request = self.service_request.SerializeToString() # Define an RPC request with the service request as payload self.rpc_request = rpc_pb2.Request() self.rpc_request.request_proto = self.serialized_request def tearDown(self): pass def test___init__(self): '''Test _LifeCycle constructor.''' self.assertEqual(self.lc.controller, self.controller, "Attribute 'controller' incorrectly initialized") self.assertEqual(self.lc.channel, self.channel, "Attribute 'channel' incorrectly initialized") self.assertEqual(self.lc.sock, None, "Attribute 'sock' incorrectly initialized") self.assertEqual(self.lc.byte_stream, None, "Attribute 'byte_stream' incorrectly initialized") self.assertEqual(self.lc.rpcResponse, None, "Attribute 'rpcResponse' incorrectly initialized") self.assertEqual(self.lc.serviceResponse, None, "Attribute 'serviceResponse' incorrectly initialized") def test_tryToValidateRequest(self): '''Test tryToValidateRequest - normal usage.''' self.assertEquals(self.lc.tryToValidateRequest(self.rpc_request), None, "tryToValidateRequest - valid request") def test_tryToValidateRequest_con_error(self): '''Test tryToValidateRequest - controller in error state.''' self.assertEquals(self.lc.tryToValidateRequest(self.rpc_request), None, "tryToValidateRequest - controller in error state") def test_tryToValidateRequest_BAD_REQUEST_PROTO(self): '''Test tryToValidateRequest - BadRequestProto error thrown.''' # A request with mandatory fields missing self.rpc_request = rpc_pb2.Request() self.lc.tryToValidateRequest(self.rpc_request) self.assertEquals(self.controller.reason, rpc_pb2.BAD_REQUEST_PROTO, "tryToValidateRequest - invalid request") self.assertEquals(self.controller.failed(), True, "tryToValidateRequest - invalid request") def test_tryToOpenSocket(self): '''Test tryToOpenSocket - normal usage.''' self.lc.tryToOpenSocket() self.assert_(self.lc.sock) def test_tryToOpenSocket_con_error(self): '''Test tryToOpenSocket - controller in error state.''' self.controller._fail = True self.lc.tryToOpenSocket() self.assertEquals(self.lc.sock, None, "tryToOpenSocket - controller in error state") def test_tryToOpenSocket_UNKNOWN_HOST(self): '''Test tryToOpenSocket - UnknownHost error thrown.''' self.socket.throwUnknownHostException() self.lc.tryToOpenSocket() self.assertEquals(self.lc.sock, None, "tryToOpenSocket - UNKNOWN_HOST error") self.assertEquals(self.controller.reason, rpc_pb2.UNKNOWN_HOST, "tryToOpenSocket - UNKNOWN_HOST error") self.assertEquals(self.controller.failed(), True, "tryToOpenSocket - UNKNOWN_HOST error") def test_tryToOpenSocket_IO_ERROR(self): '''Test tryToOpenSocket - IOError error thrown.''' self.socket.throwIOErrorException() self.lc.tryToOpenSocket() self.assertEquals(self.lc.sock, None, "tryToOpenSocket - IO_ERROR error") self.assertEquals(self.controller.reason, rpc_pb2.IO_ERROR, "tryToOpenSocket - IO_ERROR error") self.assertEquals(self.controller.failed(), True, "tryToOpenSocket - IO_ERROR error") def test_tryToSendRpcRequest(self): '''Test tryToSendRpcRequest - normal usage.''' # Instantiate the test service, and get a reference to the method method_name = 'TestMethod' service = TestServiceImpl() method = service.DESCRIPTOR.FindMethodByName(method_name) # Set the service and method names of the RPC request self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = method_name # Add the socket instance to the lifecycle object self.lc.sock = self.socket self.assertEquals( self.lc.tryToSendRpcRequest(method, self.rpc_request), None, "tryToSendRpcRequest - normal return") def test_tryToSendRpcRequest_IO_ERROR(self): '''Test tryToSendRpcRequest - IOError error thrown.''' # Instantiate the test service, and get a reference to the method method_name = 'TestMethod' service = TestServiceImpl() method = service.DESCRIPTOR.FindMethodByName(method_name) # Set the service and method names of the RPC request self.rpc_request.service_name = service.DESCRIPTOR.full_name self.rpc_request.method_name = method_name # Set the exception, and add the socket instance to the # lifecycle object self.socket.throwIOErrorException() self.lc.sock = self.socket self.assertEquals( self.lc.tryToSendRpcRequest(method, self.rpc_request), None, "tryToSendRpcRequest - IO_ERROR") self.assertEquals(self.controller.reason, rpc_pb2.IO_ERROR, "tryToSendRpcRequest - IO_ERROR error") self.assertEquals(self.controller.failed(), True, "tryToSendRpcRequest - IO_ERROR error") def test_tryToReceiveReply(self): '''Test tryToReceiveReply - normal usage.''' # Add some data to the socket msg = 'Message from server' self.socket.withInputBytes(msg) self.lc.sock = self.socket self.assertEquals(self.lc.tryToReceiveReply(), None, "tryToReceiveReply - normal usage") # Verify the socket has been closed self.assert_(self.socket.input_stream.closed, "tryToReceiveReply - normal usage") def test_tryToReceiveReply_IOError(self): '''Test tryToReceiveReply - IOError thrown.''' # Add some data to the socket msg = 'Message from server' self.socket.withInputBytes(msg) self.socket.throwIOErrorException() self.lc.sock = self.socket self.assertEquals(self.lc.tryToReceiveReply(), None, "tryToReceiveReply - IO_ERROR error") self.assertEquals(self.controller.reason, rpc_pb2.IO_ERROR, "tryToReceiveReply - IO_ERROR error") self.assertEquals(self.controller.failed(), True, "tryToReceiveReply - IO_ERROR error") # Verify the socket has been closed self.assert_(self.socket.input_stream.closed, "tryToReceiveReply - IO_ERROR error") def test_tryToParseReply(self): '''Test tryToParseReply - normal usage.''' resp_class = rpc_pb2.Response expected_response = resp_class() self.lc.byte_stream = expected_response.SerializeToString() self.assertEquals(self.lc.tryToParseReply(), None, "tryToParseReply - normal usage") def test_tryToParseReply_BAD_RESPONSE_PROTO(self): '''Test tryToParseReply - BadResponseProto error thrown.''' # Setup an arbitrary and broken bytestream self.lc.byte_stream = 'ABCD' self.assertEquals(self.lc.tryToParseReply(), None, "tryToParseReply - BAD_RESPONSE_PROTO error") self.assertEquals(self.controller.reason, rpc_pb2.BAD_RESPONSE_PROTO, "tryToParseReply - BAD_RESPONSE_PROTO error") self.assertEquals(self.controller.failed(), True, "tryToParseReply - BAD_RESPONSE_PROTO error") def test_tryToRetrieveServiceResponse(self): '''Test tryToRetrieveServiceResponse - normal usage.''' resp_class = rpc_pb2.Response expected_response = resp_class() self.lc.byte_stream = expected_response.SerializeToString() self.lc.rpcResponse = expected_response self.assertEquals(self.lc.tryToRetrieveServiceResponse(resp_class), None, "tryToRetrieveServiceResponse - normal usage") def test_tryToRetrieveServiceResponse_BAD_RESPONSE_PROTO(self): '''tryToRetrieveServiceResponse - BadResponseProto This error can never trigger, since all fields of an RPC Response() object are optional!''' pass def test_tryToRunCallback(self): '''Test tryToRunCallback - normal usage.''' callback = FakeCallback() self.lc.rpcResponse = rpc_pb2.Response() self.assertEquals(self.lc.tryToRunCallback(callback), None, "tryToRunCallback - normal usage") def suite(): '''Return the test suite containing all tests from this module.''' suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestSocketRpcChannel)) suite.addTest(unittest.makeSuite(Test__LifeCycle)) return suite if __name__ == '__main__': unittest.main() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/fake.py0000644000175000017500000001253411464555053022536 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' fake.py - Fake objects for use in unit testing. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Standard library imports import socket import traceback # Module imports import protobuf.socketrpc.channel as ch import protobuf.socketrpc.rpc_pb2 as rpc_pb2 import test_pb2 class TestServiceImpl(test_pb2.TestService): '''Implements a simple service class for use in testing.''' def __init__(self, exception=None, failmsg=None): # Set some fixed response data self.response_str_data = 'And the lord taketh away' self.response_int_data = 42 # Set the exception and fail message, if provided by the user self.exception = exception self.failmsg = failmsg def TestMethod(self, controller, request, done): # Raise an exception if one has been passed in if self.exception: raise self.exception # Extract request message contents str_data = request.str_data # Create a reply response = test_pb2.Response() response.str_data = self.response_str_data response.int_data = self.response_int_data # Simulate a user specified failure if self.failmsg: controller.handleError(-1, self.failmsg) # As per specification, call the run method of the done callback done.run(response) class FakeCallback: def __init__(self): self.response = None self.invoked = False def run(self, response): self.response = response self.invoked = True class FakeSocket: '''Stub class implementing a minimal socket interface.''' class Makefile: '''Stub class implementing the minimal interface of a socket StreamRequest.''' def __init__(self): self.stream_data = None self.closed = 0 def read(self, size=0): return self.stream_data def write(self, str): self.stream_data = str def flush(self): pass def close(self): self.closed = 1 def __init__(self): # Initialise the data streams self.input_stream = FakeSocket.Makefile() self.output_stream = FakeSocket.Makefile() # Set the error flags self.unknownhost = False self.ioerror = False def connect(self, (host, port)): if self.unknownhost: raise socket.gaierror() if self.ioerror: raise socket.error() def makefile(self, mode, buf_size=0): #Simulate an IOError on read or write if the flag is set if self.ioerror: raise socket.error if mode == 'w' or mode == 'wb': return self.output_stream elif mode == 'r' or mode == 'rb': return self.input_stream else: raise NotImplementedError('makefile mode not implemented') def shutdown(self, flag): pass def close(self): self.input_stream.close() self.output_stream.close() def getRequest(self): request = rpc_pb2.Request() request.MergeFromString(self.output_stream.stream_data) return request def throwUnknownHostException(self): self.unknownhost = True def throwIOErrorException(self): self.ioerror = True def withResponseProto(self, responseproto): rpcResponse = rpc_pb2.Response() rpcResponse.callback = True rpcResponse.response_proto = responseproto.SerializeToString() self.input_stream.stream_data = rpcResponse.SerializeToString() def withNoResponse(self, callback): rpcResponse = rpc_pb2.Response() rpcResponse.callback = callback self.input_stream.stream_data = rpcResponse.SerializeToString() def withInputBytes(self, str): self.input_stream.stream_data = str class FakeSocketFactory(ch.SocketFactory): def __init__(self): self.socket = FakeSocket() def createSocket(self): ''' Create the socket ''' return self.socket def setSocket(self, socket): ''' Used to override the default fake socket''' self.socket = socket protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/test_pb2.py0000644000175000017500000000704011464555053023346 0ustar janjan# Generated by the protocol buffer compiler. DO NOT EDIT! from google.protobuf import descriptor from google.protobuf import message from google.protobuf import reflection from google.protobuf import service from google.protobuf import service_reflection from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) DESCRIPTOR = descriptor.FileDescriptor( name='test.proto', package='protobuf.socketrpc', serialized_pb='\n\ntest.proto\x12\x12protobuf.socketrpc\"\x1b\n\x07Request\x12\x10\n\x08str_data\x18\x01 \x02(\t\".\n\x08Response\x12\x10\n\x08str_data\x18\x01 \x02(\t\x12\x10\n\x08int_data\x18\x02 \x01(\x05\x32V\n\x0bTestService\x12G\n\nTestMethod\x12\x1b.protobuf.socketrpc.Request\x1a\x1c.protobuf.socketrpc.Response') _REQUEST = descriptor.Descriptor( name='Request', full_name='protobuf.socketrpc.Request', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ descriptor.FieldDescriptor( name='str_data', full_name='protobuf.socketrpc.Request.str_data', index=0, number=1, type=9, cpp_type=9, label=2, has_default_value=False, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, extension_ranges=[], serialized_start=34, serialized_end=61, ) _RESPONSE = descriptor.Descriptor( name='Response', full_name='protobuf.socketrpc.Response', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ descriptor.FieldDescriptor( name='str_data', full_name='protobuf.socketrpc.Response.str_data', index=0, number=1, type=9, cpp_type=9, label=2, has_default_value=False, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='int_data', full_name='protobuf.socketrpc.Response.int_data', index=1, number=2, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, extension_ranges=[], serialized_start=63, serialized_end=109, ) class Request(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _REQUEST # @@protoc_insertion_point(class_scope:protobuf.socketrpc.Request) class Response(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _RESPONSE # @@protoc_insertion_point(class_scope:protobuf.socketrpc.Response) _TESTSERVICE = descriptor.ServiceDescriptor( name='TestService', full_name='protobuf.socketrpc.TestService', file=DESCRIPTOR, index=0, options=None, serialized_start=111, serialized_end=197, methods=[ descriptor.MethodDescriptor( name='TestMethod', full_name='protobuf.socketrpc.TestService.TestMethod', index=0, containing_service=None, input_type=_REQUEST, output_type=_RESPONSE, options=None, ), ]) class TestService(service.Service): __metaclass__ = service_reflection.GeneratedServiceType DESCRIPTOR = _TESTSERVICE class TestService_Stub(TestService): __metaclass__ = service_reflection.GeneratedServiceStubType DESCRIPTOR = _TESTSERVICE # @@protoc_insertion_point(module_scope) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/test.proto0000644000175000017500000000264311464555052023321 0ustar janjan// Copyright (c) 2009 Shardul Deo // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // Author: Shardul Deo // // Protobufs used for unit tests. package protobuf.socketrpc; message Request { required string str_data = 1; } message Response { required string str_data = 1; optional int32 int_data = 2; } service TestService { rpc TestMethod(Request) returns(Response); }protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/tests/run_tests.py0000644000175000017500000000337011464555053023654 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. '''run_tests.py - Run all unit tests for the protobuf.* package. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) May 2009 ''' # Standard library imports import unittest # Module imports import channel_test import controller_test import error_test import server_test import service_test if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(channel_test.suite()) suite.addTest(controller_test.suite()) suite.addTest(error_test.suite()) suite.addTest(server_test.suite()) suite.addTest(service_test.suite()) unittest.TextTestRunner(verbosity=0).run(suite) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/__init__.py0000644000175000017500000000223311464555053022220 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from service import RpcThread, RpcService protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/channel.py0000644000175000017500000002362311464555053022077 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' channel.py - Socket implementation of Google's Protocol Buffers RPC service interface. This package contains classes providing a socket implementation of the RPCChannel abstract class. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Standard library imports import socket # Third party imports import google.protobuf.service as service # Module imports import rpc_pb2 as rpc_pb from protobuf.socketrpc import logger from protobuf.socketrpc.controller import SocketRpcController from protobuf.socketrpc import error # Configure package logging log = logger.getLogger(__name__) class SocketFactory(): '''A factory class for providing socket instances.''' def createSocket(self): '''Creates and returns a TCP socket.''' return socket.socket(socket.AF_INET, socket.SOCK_STREAM) class SocketRpcChannel(service.RpcChannel): '''Socket implementation of an RpcChannel. An RpcChannel represents a communication line to a service which can be used to call the service's methods. Example: channel = SocketRpcChannel(host='myservicehost') controller = channel.newController() service = MyService_Stub(channel) service.MyMethod(controller,request,callback) ''' def __init__(self, host='localhost', port=8090, socketFactory=SocketFactory()): '''SocketRpcChannel to connect to a socket server on a user defined port. ''' self.host = host self.port = port self.sockFactory = socketFactory def newController(self): '''Create and return a socket controller.''' return SocketRpcController() def validateRequest(self, request): '''Validate the client request against the protocol file.''' # Check the request is correctly initialized if not request.IsInitialized(): raise error.BadRequestProtoError('Client request is missing\ mandatory fields') def openSocket(self, host, port): '''Open a socket connection to a given host and port.''' # Open socket sock = self.sockFactory.createSocket() # Connect socket to server - defined by host and port arguments try: sock.connect((host, port)) except socket.gaierror: msg = "Could not find host %s" % host # Cleanup and re-raise the exception with the caller self.closeSocket(sock) raise error.UnknownHostError(msg) except socket.error: msg = "Could not open I/O for %s:%s" % (host, port) # Cleanup and re-raise the exception with the caller self.closeSocket(sock) raise error.IOError(msg) return sock def createRpcRequest(self, method, request): '''Wrap the user's request in an RPC protocol message.''' rpcRequest = rpc_pb.Request() rpcRequest.request_proto = request.SerializeToString() rpcRequest.service_name = method.containing_service.full_name rpcRequest.method_name = method.name return rpcRequest def sendRpcMessage(self, sock, rpcRequest): '''Send an RPC request to the server.''' try: wfile = sock.makefile('w') wfile.write(rpcRequest.SerializeToString()) wfile.flush() sock.shutdown(socket.SHUT_WR) except socket.error: self.closeSocket(sock) raise error.IOError("Error writing data to server") def recvRpcMessage(self, sock): '''Handle reading an RPC reply from the server.''' try: rfile = sock.makefile('r') byte_stream = rfile.read() except socket.error: raise error.IOError("Error reading data from server") finally: self.closeSocket(sock) return byte_stream def parseResponse(self, byte_stream, response_class): '''Parse a bytestream into a Response object of the requested type.''' # Instantiate a Response object of the requested type response = response_class() # Catch anything which isn't a valid PB bytestream try: response.ParseFromString(byte_stream) except Exception, e: raise error.BadResponseProtoError("Invalid response \ (decodeError): " + str(e)) # Check the response has all mandatory fields initialized if not response.IsInitialized(): raise error.BadResponseProtoError("Response not initialized") return response def closeSocket(self, sock): '''Close the socket.''' if sock: try: sock.close() except: pass return def CallMethod(self, method, controller, request, response_class, done): '''Call the RPC method. This method uses a LifeCycle instance to manage communication with the server. ''' lifecycle = _LifeCycle(controller, self) lifecycle.tryToValidateRequest(request) lifecycle.tryToOpenSocket() lifecycle.tryToSendRpcRequest(method, request) lifecycle.tryToReceiveReply() lifecycle.tryToParseReply() lifecycle.tryToRetrieveServiceResponse(response_class) lifecycle.tryToRunCallback(done) class _LifeCycle(): '''Represents and manages the lifecycle of an RPC request.''' def __init__(self, controller, channel): self.controller = controller self.channel = channel self.sock = None self.byte_stream = None self.rpcResponse = None self.serviceResponse = None def tryToValidateRequest(self, request): if self.controller.failed(): return # Validate the request object try: self.channel.validateRequest(request) except error.BadRequestProtoError, e: self.controller.handleError(rpc_pb.BAD_REQUEST_PROTO, e.message) def tryToOpenSocket(self): if self.controller.failed(): return # Open socket try: self.sock = self.channel.openSocket(self.channel.host,\ self.channel.port) except error.UnknownHostError, e: self.controller.handleError(rpc_pb.UNKNOWN_HOST,\ e.message) except error.IOError, e: self.controller.handleError(rpc_pb.IO_ERROR, e.message) def tryToSendRpcRequest(self, method, request): if self.controller.failed(): return # Create an RPC request protobuf rpcRequest = self.channel.createRpcRequest(method, request) # Send the request over the socket try: self.channel.sendRpcMessage(self.sock, rpcRequest) except error.IOError, e: self.controller.handleError(rpc_pb.IO_ERROR, e.message) def tryToReceiveReply(self): if self.controller.failed(): return # Get the reply try: self.byte_stream = self.channel.recvRpcMessage(self.sock) except error.IOError, e: self.controller.handleError(rpc_pb.IO_ERROR, e.message) def tryToParseReply(self): if self.controller.failed(): return #Parse RPC reply try: self.rpcResponse = self.channel.parseResponse(self.byte_stream, rpc_pb.Response) except error.BadResponseProtoError, e: self.controller.handleError(rpc_pb.BAD_RESPONSE_PROTO, e.message) def tryToRetrieveServiceResponse(self, response_class): if self.controller.failed(): return if self.rpcResponse.HasField('error'): self.controller.handleError(self.rpcResponse.error_reason, self.rpcResponse.error) else: # Extract service response try: self.serviceResponse = self.channel.parseResponse( self.rpcResponse.response_proto, response_class) except error.BadResponseProtoError, e: self.controller.handleError(rpc_pb.BAD_RESPONSE_PROTO, e.message) def tryToRunCallback(self, done): if self.controller.failed(): return # Check for any outstanding errors if(self.rpcResponse.error): self.controller.handleError(self.rpcResponse.error_reason, self.rpcResponse.error) # Run the callback, if there is one if done: done.run(self.serviceResponse) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/rpc_pb2.py0000644000175000017500000001467411464555053022024 0ustar janjan# Generated by the protocol buffer compiler. DO NOT EDIT! from google.protobuf import descriptor from google.protobuf import message from google.protobuf import reflection from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) DESCRIPTOR = descriptor.FileDescriptor( name='rpc.proto', package='protobuf.socketrpc', serialized_pb='\n\trpc.proto\x12\x12protobuf.socketrpc\"K\n\x07Request\x12\x14\n\x0cservice_name\x18\x01 \x02(\t\x12\x13\n\x0bmethod_name\x18\x02 \x02(\t\x12\x15\n\rrequest_proto\x18\x03 \x02(\x0c\"\x81\x01\n\x08Response\x12\x16\n\x0eresponse_proto\x18\x01 \x01(\x0c\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x12\x17\n\x08\x63\x61llback\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x35\n\x0c\x65rror_reason\x18\x04 \x01(\x0e\x32\x1f.protobuf.socketrpc.ErrorReason*\xd9\x01\n\x0b\x45rrorReason\x12\x14\n\x10\x42\x41\x44_REQUEST_DATA\x10\x00\x12\x15\n\x11\x42\x41\x44_REQUEST_PROTO\x10\x01\x12\x15\n\x11SERVICE_NOT_FOUND\x10\x02\x12\x14\n\x10METHOD_NOT_FOUND\x10\x03\x12\r\n\tRPC_ERROR\x10\x04\x12\x0e\n\nRPC_FAILED\x10\x05\x12\x19\n\x15INVALID_REQUEST_PROTO\x10\x06\x12\x16\n\x12\x42\x41\x44_RESPONSE_PROTO\x10\x07\x12\x10\n\x0cUNKNOWN_HOST\x10\x08\x12\x0c\n\x08IO_ERROR\x10\tB4\n!com.googlecode.protobuf.socketrpcB\x0fSocketRpcProtos') _ERRORREASON = descriptor.EnumDescriptor( name='ErrorReason', full_name='protobuf.socketrpc.ErrorReason', filename=None, file=DESCRIPTOR, values=[ descriptor.EnumValueDescriptor( name='BAD_REQUEST_DATA', index=0, number=0, options=None, type=None), descriptor.EnumValueDescriptor( name='BAD_REQUEST_PROTO', index=1, number=1, options=None, type=None), descriptor.EnumValueDescriptor( name='SERVICE_NOT_FOUND', index=2, number=2, options=None, type=None), descriptor.EnumValueDescriptor( name='METHOD_NOT_FOUND', index=3, number=3, options=None, type=None), descriptor.EnumValueDescriptor( name='RPC_ERROR', index=4, number=4, options=None, type=None), descriptor.EnumValueDescriptor( name='RPC_FAILED', index=5, number=5, options=None, type=None), descriptor.EnumValueDescriptor( name='INVALID_REQUEST_PROTO', index=6, number=6, options=None, type=None), descriptor.EnumValueDescriptor( name='BAD_RESPONSE_PROTO', index=7, number=7, options=None, type=None), descriptor.EnumValueDescriptor( name='UNKNOWN_HOST', index=8, number=8, options=None, type=None), descriptor.EnumValueDescriptor( name='IO_ERROR', index=9, number=9, options=None, type=None), ], containing_type=None, options=None, serialized_start=243, serialized_end=460, ) BAD_REQUEST_DATA = 0 BAD_REQUEST_PROTO = 1 SERVICE_NOT_FOUND = 2 METHOD_NOT_FOUND = 3 RPC_ERROR = 4 RPC_FAILED = 5 INVALID_REQUEST_PROTO = 6 BAD_RESPONSE_PROTO = 7 UNKNOWN_HOST = 8 IO_ERROR = 9 _REQUEST = descriptor.Descriptor( name='Request', full_name='protobuf.socketrpc.Request', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ descriptor.FieldDescriptor( name='service_name', full_name='protobuf.socketrpc.Request.service_name', index=0, number=1, type=9, cpp_type=9, label=2, has_default_value=False, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='method_name', full_name='protobuf.socketrpc.Request.method_name', index=1, number=2, type=9, cpp_type=9, label=2, has_default_value=False, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='request_proto', full_name='protobuf.socketrpc.Request.request_proto', index=2, number=3, type=12, cpp_type=9, label=2, has_default_value=False, default_value="", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, extension_ranges=[], serialized_start=33, serialized_end=108, ) _RESPONSE = descriptor.Descriptor( name='Response', full_name='protobuf.socketrpc.Response', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ descriptor.FieldDescriptor( name='response_proto', full_name='protobuf.socketrpc.Response.response_proto', index=0, number=1, type=12, cpp_type=9, label=1, has_default_value=False, default_value="", message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='error', full_name='protobuf.socketrpc.Response.error', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='callback', full_name='protobuf.socketrpc.Response.callback', index=2, number=3, type=8, cpp_type=7, label=1, has_default_value=True, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), descriptor.FieldDescriptor( name='error_reason', full_name='protobuf.socketrpc.Response.error_reason', index=3, number=4, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], enum_types=[ ], options=None, is_extendable=False, extension_ranges=[], serialized_start=111, serialized_end=240, ) _RESPONSE.fields_by_name['error_reason'].enum_type = _ERRORREASON class Request(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _REQUEST # @@protoc_insertion_point(class_scope:protobuf.socketrpc.Request) class Response(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _RESPONSE # @@protoc_insertion_point(class_scope:protobuf.socketrpc.Response) # @@protoc_insertion_point(module_scope) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/0000755000175000017500000000000011464617602021724 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/0000755000175000017500000000000011464617602024077 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/hello_world_pb2.py0000644000175000017500000000710311464555053027530 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Generated by the protocol buffer compiler. DO NOT EDIT! from google.protobuf import descriptor from google.protobuf import message from google.protobuf import reflection from google.protobuf import service from google.protobuf import service_reflection from google.protobuf import descriptor_pb2 _HELLOREQUEST = descriptor.Descriptor( name='HelloRequest', full_name='protobuf.socketrpc.HelloRequest', filename='hello_world.proto', containing_type=None, fields=[ descriptor.FieldDescriptor( name='my_name', full_name='protobuf.socketrpc.HelloRequest.my_name', index=0, number=2, type=9, cpp_type=9, label=2, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], # TODO(robinson): Implement. enum_types=[ ], options=None) _HELLORESPONSE = descriptor.Descriptor( name='HelloResponse', full_name='protobuf.socketrpc.HelloResponse', filename='hello_world.proto', containing_type=None, fields=[ descriptor.FieldDescriptor( name='hello_world', full_name='protobuf.socketrpc.HelloResponse.hello_world', index=0, number=1, type=9, cpp_type=9, label=2, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], # TODO(robinson): Implement. enum_types=[ ], options=None) class HelloRequest(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _HELLOREQUEST class HelloResponse(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _HELLORESPONSE _HELLOWORLDSERVICE = descriptor.ServiceDescriptor( name='HelloWorldService', full_name='protobuf.socketrpc.HelloWorldService', index=0, options=None, methods=[ descriptor.MethodDescriptor( name='HelloWorld', full_name='protobuf.socketrpc.HelloWorldService.HelloWorld', index=0, containing_service=None, input_type=_HELLOREQUEST, output_type=_HELLORESPONSE, options=None, ), ]) class HelloWorldService(service.Service): __metaclass__ = service_reflection.GeneratedServiceType DESCRIPTOR = _HELLOWORLDSERVICE class HelloWorldService_Stub(HelloWorldService): __metaclass__ = service_reflection.GeneratedServiceStubType DESCRIPTOR = _HELLOWORLDSERVICE protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/HelloWorldServiceImpl.py0000644000175000017500000000366611464555053030703 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. '''HelloWorldServiceImpl.py - 'Hello world' service implementation example. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Zach Walker (zwalker@lcogt.net) May 2009 ''' import hello_world_pb2 import time class HelloWorldImpl(hello_world_pb2.HelloWorldService): def HelloWorld(self, controller, request, done): print "In HelloWorld!" # Print the request print request # Extract name from the message received name = request.my_name # Create a reply response = hello_world_pb2.HelloResponse() response.hello_world = 'Hello %s' % name # Sleeping to show asynchronous behavior on client end. time.sleep(1) # We're done, call the run method of the done callback done.run(response) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/hello_world.proto0000644000175000017500000000276111464555053027505 0ustar janjan// Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // Author: Eric Saunders (esaunders@lcogt.net) // // Protobuf definition file for the HelloWorld service. package protobuf.socketrpc; message HelloRequest { required string my_name = 2; } message HelloResponse { required string hello_world = 1; } service HelloWorldService { rpc HelloWorld(HelloRequest) returns(HelloResponse); } protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/__init__.py0000644000175000017500000000216011464555053026210 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/run_server.py0000644000175000017500000000357311464555053026654 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' run_server.py - A simple front-end to demo the RPC server implementation. Author: Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Add main protobuf module to classpath import sys sys.path.append('../../main') # Import required RPC modules import hello_world_pb2 import protobuf.socketrpc.server as server import HelloWorldServiceImpl as impl # Create and register the service # Note that this is an instantiation of the implementation class, # *not* the class defined in the proto file. hello_world_service = impl.HelloWorldImpl() server = server.SocketRpcServer(8090) server.registerService(hello_world_service) # Start the server print 'Serving on port 8090' server.run() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/helloworld/run_client.py0000644000175000017500000000505311464555053026617 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' run_client.py - A simple front-end to demo the RPC client implementation. Authors: Eric Saunders (esaunders@lcogt.net) Martin Norbury (mnorbury@lcogt.net) Zach Walker (zwalker@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Add main protobuf module to classpath import sys sys.path.append('../../main') import traceback # Import required RPC modules import hello_world_pb2 from protobuf.socketrpc import RpcService # Configure logging import logging log = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) # Server details hostname = 'localhost' port = 8090 # Create a request request = hello_world_pb2.HelloRequest() request.my_name = 'Zach' # Create a new service instance service = RpcService(hello_world_pb2.HelloWorldService_Stub, port, hostname) def callback(request, response): """Define a simple async callback.""" log.info('Asynchronous response :' + response.__str__()) # Make an asynchronous call try: log.info('Making asynchronous call') response = service.HelloWorld(request, callback=callback) except Exception, ex: log.exception(ex) # Make a synchronous call try: log.info('Making synchronous call') response = service.HelloWorld(request, timeout=10000) log.info('Synchronous response: ' + response.__str__()) except Exception, ex: log.exception(ex) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/0000755000175000017500000000000011464617602022662 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/__init__.py0000644000175000017500000000216011464555053024773 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/time_pb2.py0000644000175000017500000000622711464555053024745 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # Generated by the protocol buffer compiler. DO NOT EDIT! from google.protobuf import descriptor from google.protobuf import message from google.protobuf import reflection from google.protobuf import service from google.protobuf import service_reflection from google.protobuf import descriptor_pb2 _TIMEREQUEST = descriptor.Descriptor( name='TimeRequest', full_name='protobuf.socketrpc.TimeRequest', filename='time.proto', containing_type=None, fields=[ ], extensions=[ ], nested_types=[], # TODO(robinson): Implement. enum_types=[ ], options=None) _TIMERESPONSE = descriptor.Descriptor( name='TimeResponse', full_name='protobuf.socketrpc.TimeResponse', filename='time.proto', containing_type=None, fields=[ descriptor.FieldDescriptor( name='str_time', full_name='protobuf.socketrpc.TimeResponse.str_time', index=0, number=1, type=9, cpp_type=9, label=2, default_value=unicode("", "utf-8"), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), ], extensions=[ ], nested_types=[], # TODO(robinson): Implement. enum_types=[ ], options=None) class TimeRequest(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _TIMEREQUEST class TimeResponse(message.Message): __metaclass__ = reflection.GeneratedProtocolMessageType DESCRIPTOR = _TIMERESPONSE _TIMESERVICE = descriptor.ServiceDescriptor( name='TimeService', full_name='protobuf.socketrpc.TimeService', index=0, options=None, methods=[ descriptor.MethodDescriptor( name='getTime', full_name='protobuf.socketrpc.TimeService.getTime', index=0, containing_service=None, input_type=_TIMEREQUEST, output_type=_TIMERESPONSE, options=None, ), ]) class TimeService(service.Service): __metaclass__ = service_reflection.GeneratedServiceType DESCRIPTOR = _TIMESERVICE class TimeService_Stub(TimeService): __metaclass__ = service_reflection.GeneratedServiceStubType DESCRIPTOR = _TIMESERVICE protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/run_server.py0000644000175000017500000000516711464555053025440 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' run_server.py - An example server using the python socket implementation of the Google Protocol Buffers. This module is an executable script demonstrating the usage of the python socket implementation of the Google Protocol Buffers. This script starts a socket server running on localhost:8090. Once running, the run_client.py script can be used to test the TimeService.getTime remote procedure call (RPC). Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Add main protobuf module to classpath import sys sys.path.append('../../main') from protobuf.socketrpc.server import SocketRpcServer import time_pb2 as proto import time import logging log = logging.getLogger(__name__) port = 8090 class TimeService(proto.TimeService): '''An example service implementation.''' def getTime(self, controller, request, done): '''Get the current time and return as a response message via the callback routine provide.''' log.info('Called TestMethod') # Create response message response = proto.TimeResponse() response.str_time = time.asctime() # Call provided callback with response message done.run(response) if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) # Create service service = TimeService() server = SocketRpcServer(port) server.registerService(service) server.run() protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/run_client.py0000644000175000017500000000440511464555053025402 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' run_client.py - An example client using the python socket implementation of the Google Protocol Buffers. This module is an executable script demonstrating the usage of the python socket implementation of the Google Protocol Buffers. To work correctly, the script requires a server to be running first (i.e. run_server.py). Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Zach Walker (zwalker@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Add main protobuf module to classpath import sys sys.path.append('../../main') import time_pb2 as proto from protobuf.socketrpc import RpcService import logging log = logging.getLogger(__name__) hostname = 'localhost' port = 8090 if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) log.debug("test") # Create request message request = proto.TimeRequest() service = RpcService(proto.TimeService_Stub, port, hostname) try: response = service.getTime(request, timeout=1000) log.info(response) except Exception, ex: log.exception(ex) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/time/time.proto0000644000175000017500000000251711464555053024713 0ustar janjan// Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. package protobuf.socketrpc; message TimeRequest { } message TimeResponse { required string str_time = 1; } service TimeService { rpc getTime(TimeRequest) returns(TimeResponse); } protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/examples/__init__.py0000644000175000017500000000000011464555053024024 0ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf/socketrpc/rpc.proto0000644000175000017500000000533111464555053021762 0ustar janjan// Copyright (c) 2009 Shardul Deo // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // Author: Shardul Deo // // Protobufs needed for socket rpcs. package protobuf.socketrpc; option java_package = "com.googlecode.protobuf.socketrpc"; option java_outer_classname = "SocketRpcProtos"; message Request { // RPC service full name required string service_name = 1; // RPC method name required string method_name = 2; // RPC request proto required bytes request_proto = 3; } message Response { // RPC response proto optional bytes response_proto = 1; // Error, if any optional string error = 2; // Was callback invoked optional bool callback = 3 [default = false]; // Error Reason optional ErrorReason error_reason = 4; } // Possible error reasons // The server-side errors are returned in the response from the server. // The client-side errors are returned by the client-side code when it doesn't // have a response from the server. enum ErrorReason { // Server-side errors BAD_REQUEST_DATA = 0; // Server received bad request data BAD_REQUEST_PROTO = 1; // Server received bad request proto SERVICE_NOT_FOUND = 2; // Service not found on server METHOD_NOT_FOUND = 3; // Method not found on server RPC_ERROR = 4; // Rpc threw exception on server RPC_FAILED = 5; // Rpc failed on server // Client-side errors (these are returned by the client-side code) INVALID_REQUEST_PROTO = 6; // Rpc was called with invalid request proto BAD_RESPONSE_PROTO = 7; // Server returned a bad response proto UNKNOWN_HOST = 8; // Could not find supplied host IO_ERROR = 9; // I/O error while communicating with server } protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/error.py0000644000175000017500000000776711464555053021633 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' error.py - Exception classes for the protobuf package. This package contains exception classes mapped to the rpc.proto file. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Module imports from protobuf.socketrpc import rpc_pb2 as rpc_pb class ProtobufError(Exception): '''Base exception class for RPC protocol buffer errors.''' def __init__(self, message, rpc_error_code): '''ProtobufError constructor. message - Message string detailing error. rpc_error_code - Error code from rpc.proto file. ''' self.message = message self.rpc_error_code = rpc_error_code class BadRequestDataError(ProtobufError): '''Exception generated for a BadRequestDataError.''' def __init__(self, message): super(BadRequestDataError, self).__init__( message, rpc_pb.BAD_REQUEST_DATA) class BadRequestProtoError(ProtobufError): '''Exception generated for a BadRequestProtoError.''' def __init__(self, message): super(BadRequestProtoError, self).__init__( message, rpc_pb.BAD_REQUEST_PROTO) class ServiceNotFoundError(ProtobufError): '''Exception generated for a ServiceNotFoundError.''' def __init__(self, message): super(ServiceNotFoundError, self).__init__( message, rpc_pb.SERVICE_NOT_FOUND) class MethodNotFoundError(ProtobufError): '''Exception generated for a MethodNotFoundError.''' def __init__(self, message): super(MethodNotFoundError, self).__init__( message, rpc_pb.METHOD_NOT_FOUND) class RpcError(ProtobufError): '''Exception generated for an RpcError.''' def __init__(self, message): super(RpcError, self).__init__(message, rpc_pb.RPC_ERROR) class RpcFailed(ProtobufError): '''Exception generated for an RpcFailed.''' def __init__(self, message): super(RpcFailed, self).__init__(message, rpc_pb.RPC_FAILED) class InvalidRequestProtoError(ProtobufError): '''Exception generated for an InvalidRequestProtoError.''' def __init__(self, message): super(InvalidRequestProtoError, self).__init__( message, rpc_pb.INVALID_REQUEST_PROTO) class BadResponseProtoError(ProtobufError): '''Exception generated for a BadResponseProtoError.''' def __init__(self, message): super(BadResponseProtoError, self).__init__( message, rpc_pb.BAD_RESPONSE_PROTO) class UnknownHostError(ProtobufError): '''Exception generated for an UnknownHostError.''' def __init__(self, message): super(UnknownHostError, self).__init__(message, rpc_pb.UNKNOWN_HOST) class IOError(ProtobufError): '''Exception generated for an IOError.''' def __init__(self, message): super(IOError, self).__init__(message, rpc_pb.IO_ERROR) protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/controller.py0000644000175000017500000000476211464555053022655 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ''' controller.py - Socket implementation of Google's Protocol Buffers RPC service interface. This package contains classes providing a socket implementation of the RPCController abstract class. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) Jan Dittberner (jan@dittberner.info) May 2009, Nov 2010 ''' # Third-party imports import google.protobuf.service as service # Module imports from protobuf.socketrpc import logger class SocketRpcController(service.RpcController): ''' RpcController implementation to be used by the SocketRpcChannel class. The RpcController is used to mediate a single method call. ''' def __init__(self): '''Constructor which initializes the controller's state.''' self._fail = False self._error = None self.reason = None def handleError(self, error_code, message): '''Log and set the controller state.''' self._fail = True self.reason = error_code self._error = message def reset(self): '''Resets the controller i.e. clears the error state.''' self._fail = False self._error = None self.reason = None def failed(self): '''Returns True if the controller is in a failed state.''' return self._fail def error(self): return self._error protobuf.socketrpc-1.3.2/src/protobuf/socketrpc/logger.py0000644000175000017500000000413711464555053021745 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory (www.lcogt.net) # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. '''protobuf/logger.py - Module for configuring the package level logging. This module contains a convenience function for creating and retrieving a logger with a given name. In addition a Null handler is added to the logger to prevent client software not implementing the logging package from receiving "No handler" error messages. Authors: Martin Norbury (mnorbury@lcogt.net) Eric Saunders (esaunders@lcogt.net) May 2009 ''' # Standard library imports import logging class _NullHandler(logging.Handler): ''' NULL logging handler. A null logging handler to prevent clients that don't require the logging package from reporting no handlers found. ''' def emit(self, record): ''' Override the emit function to do nothing. ''' pass def getLogger(name): ''' Create and return a logger with the specified name. ''' # Create logger and add a default NULL handler log = logging.getLogger(name) log.addHandler(_NullHandler()) return log protobuf.socketrpc-1.3.2/src/protobuf/__init__.py0000644000175000017500000000000011464555053020211 0ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf.socketrpc.egg-info/0000755000175000017500000000000011464617602021577 5ustar janjanprotobuf.socketrpc-1.3.2/src/protobuf.socketrpc.egg-info/dependency_links.txt0000644000175000017500000000000111464617602025645 0ustar janjan protobuf.socketrpc-1.3.2/src/protobuf.socketrpc.egg-info/SOURCES.txt0000644000175000017500000000312211464617602023461 0ustar janjanChangeLog LICENSE setup.py src/protobuf/__init__.py src/protobuf.socketrpc.egg-info/PKG-INFO src/protobuf.socketrpc.egg-info/SOURCES.txt src/protobuf.socketrpc.egg-info/dependency_links.txt src/protobuf.socketrpc.egg-info/top_level.txt src/protobuf/socketrpc/__init__.py src/protobuf/socketrpc/channel.py src/protobuf/socketrpc/controller.py src/protobuf/socketrpc/error.py src/protobuf/socketrpc/logger.py src/protobuf/socketrpc/rpc.proto src/protobuf/socketrpc/rpc_pb2.py src/protobuf/socketrpc/server.py src/protobuf/socketrpc/service.py src/protobuf/socketrpc/examples/__init__.py src/protobuf/socketrpc/examples/helloworld/HelloWorldServiceImpl.py src/protobuf/socketrpc/examples/helloworld/__init__.py src/protobuf/socketrpc/examples/helloworld/hello_world.proto src/protobuf/socketrpc/examples/helloworld/hello_world_pb2.py src/protobuf/socketrpc/examples/helloworld/run_client.py src/protobuf/socketrpc/examples/helloworld/run_server.py src/protobuf/socketrpc/examples/time/__init__.py src/protobuf/socketrpc/examples/time/run_client.py src/protobuf/socketrpc/examples/time/run_server.py src/protobuf/socketrpc/examples/time/time.proto src/protobuf/socketrpc/examples/time/time_pb2.py src/protobuf/socketrpc/tests/__init__.py src/protobuf/socketrpc/tests/channel_test.py src/protobuf/socketrpc/tests/controller_test.py src/protobuf/socketrpc/tests/error_test.py src/protobuf/socketrpc/tests/fake.py src/protobuf/socketrpc/tests/run_tests.py src/protobuf/socketrpc/tests/server_test.py src/protobuf/socketrpc/tests/service_test.py src/protobuf/socketrpc/tests/test.proto src/protobuf/socketrpc/tests/test_pb2.pyprotobuf.socketrpc-1.3.2/src/protobuf.socketrpc.egg-info/top_level.txt0000644000175000017500000000001111464617602024321 0ustar janjanprotobuf protobuf.socketrpc-1.3.2/src/protobuf.socketrpc.egg-info/PKG-INFO0000644000175000017500000000162411464617602022677 0ustar janjanMetadata-Version: 1.0 Name: protobuf.socketrpc Version: 1.3.2 Summary: a Python implementation of protobuf RPC over sockets Home-page: http://code.google.com/p/protobuf-socket-rpc/ Author: Shardul Deo Author-email: shardul.deo@gmail.com License: UNKNOWN Description: Google's protocol buffer library makes writing rpc services easy, but it does not contain a rpc implementation. The transport details are left up to the user to implement. This is a simple tcp/ip socket based rpc implementation in java and python for people who want a simple implementation of their protobuf rpc services. Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules protobuf.socketrpc-1.3.2/setup.cfg0000644000175000017500000000007311464617602015303 0ustar janjan[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 protobuf.socketrpc-1.3.2/ChangeLog0000644000175000017500000000300011464617441015226 0ustar janjanVersion 1.3.2 (SVN Revision 89) 2010-11-04 * Use a more pythonic directory structure to allow better use of setuptools/distribute features * Add metadata to setup.py * Rename Python module from protobuf to protobuf.socketrpc to avoid name clashes * Join thread instead of busy waiting for synchronous calls * Protobuf 2.3.0 compatible * Fixes for Issue 11 (Cannot create different server side handlers for the same service) and Issue 12 (Exceptions on server not propogated to client) * Fixed unit tests Version 1.3.1 (SVN Revision 46) 2009-12-21 * Added Service class to make rpc calls cleaner and hide some of the setup details Version 1.3 (SVN Revision 33) 2009-10-04 * Protobuf 2.2.0 compatible and dependent. * Moving error reasons out of response message into its own top level type in the proto. Added client side error reasons to the error codes to be consistent. Version 1.2 (SVN Revision 12) 2009-02-14 * Errors that occur on server side are not relayed back to client. Client has new error reasons for them in the controller. * Client callback behavior is faithful replication of server callback scenarios: - Callback is called with good response. - Callback is not called. - Callback is called with null. - Callback is called with empty protocol buffer. * Added comprehensive unit tests for client and server. Version 1.1 (SVN Revision 9) 2009-02-06 * Added error handling. When errors occur, the client can find out what error occurred from the controller. * Started adding unit tests. protobuf.socketrpc-1.3.2/PKG-INFO0000644000175000017500000000162411464617602014562 0ustar janjanMetadata-Version: 1.0 Name: protobuf.socketrpc Version: 1.3.2 Summary: a Python implementation of protobuf RPC over sockets Home-page: http://code.google.com/p/protobuf-socket-rpc/ Author: Shardul Deo Author-email: shardul.deo@gmail.com License: UNKNOWN Description: Google's protocol buffer library makes writing rpc services easy, but it does not contain a rpc implementation. The transport details are left up to the user to implement. This is a simple tcp/ip socket based rpc implementation in java and python for people who want a simple implementation of their protobuf rpc services. Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules protobuf.socketrpc-1.3.2/setup.py0000644000175000017500000000461111464617035015176 0ustar janjan#!/usr/bin/python # Copyright (c) 2009 Las Cumbres Observatory. # Copyright (c) 2010 Jan Dittberner # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from setuptools import setup, find_packages DESCRIPTION = """Google's protocol buffer library makes writing rpc services easy, but it does not contain a rpc implementation. The transport details are left up to the user to implement. This is a simple tcp/ip socket based rpc implementation in java and python for people who want a simple implementation of their protobuf rpc services. """ setup( name="protobuf.socketrpc", version="1.3.2", description="a Python implementation of protobuf RPC over sockets", long_description=DESCRIPTION, url='http://code.google.com/p/protobuf-socket-rpc/', author='Shardul Deo', author_email='shardul.deo@gmail.com', classifiers=[ 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries :: Python Modules'], packages=find_packages('src', exclude=[ '*.*.tests', '*.*.examples', '*.*.examples.*']), package_dir={'': 'src'}, # protobuf is not easy_install'able (yet) see # http://code.google.com/p/protobuf/issues/detail?id=66 #install_requires=['protobuf>=2.2'], test_suite='protobuf.socketrpc.tests', )