Skip to content

Commit

Permalink
Added documentation for hello example (py4j distribution provider)
Browse files Browse the repository at this point in the history
  • Loading branch information
scottslewis committed Jun 5, 2018
1 parent 2d37fbf commit 0549918
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 28 deletions.
2 changes: 1 addition & 1 deletion pelix/rsa/endpointdescription.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def get_framework_uuid(self):

def get_osgi_basic_timeout(self):
timeout = self.get_properties().get(OSGI_BASIC_TIMEOUT_INTENT,None)
return int(timeout) if timeout else None
return (int(timeout)/1000) if timeout else None

def get_id(self):
"""
Expand Down
5 changes: 3 additions & 2 deletions pelix/rsa/providers/distribution/py4j.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def supports_export(self, exported_configs, service_intents, export_props):

@Validate
def _validate(self,context):
### XXX here is where we can get java and python ports
### here is where we can get java and python ports
## and change the defaults for connecting
try:
self._bridge = Py4jServiceBridge(service_listener=self,gateway_parameters=GatewayParameters(port=self._javaport),
Expand All @@ -193,7 +193,8 @@ def _validate(self,context):
raise e
# Once bridge is connected, instantiate container using bridge id
container_props = self._prepare_container_props(self._supported_intents, None)
container_props[ECF_PY4J_DEFAULT_SERVICE_TIMEOUT] = self._default_service_timeout
if self._default_service_timeout:
container_props[ECF_PY4J_DEFAULT_SERVICE_TIMEOUT] = self._default_service_timeout
self._container = self._ipopo.instantiate(self._config_name,self._bridge.get_id(),container_props)

@Invalidate
Expand Down
21 changes: 12 additions & 9 deletions samples/rsa/helloconsumer.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
from pelix.ipopo.decorators import ComponentFactory,Instantiate,Requires,Validate

@ComponentFactory("remote-hello-consumer-factory")
# The '(service.imported=*)' filter only allows remote hello service proxies to be injected
# The '(service.imported=*)' filter only allows remote services to be injected
@Requires("_helloservice", "org.eclipse.ecf.examples.hello.IHello", False, False, "(service.imported=*)", False)
@Instantiate("remote-hello-consumer")
class RemoteHelloConsumer(object):

def __init__(self):
self._helloservice = None
self._name = 'Python'
self._message = 'Hello Java'
self._msg = 'Hello Java'

@Validate
def _validate(self,bcontext):
def _validate(self,bundle_context):
# call it!
resp = self._helloservice.sayHello(self._name, self._message)
print("{0} IHello service consumer received response: {1}".format(self._name,resp))
# call sayHelloAsync which returns future and we lambda to print the result when done
self._helloservice.sayHelloAsync(self._name, self._message).add_done_callback(lambda f: print('async respon: {0}'.format(f.result())))
print("done with helloimpl _validate method")

resp = self._helloservice.sayHello(self._name+'Sync', self._msg)
print("{0} IHello service consumer received sync response: {1}".format(self._name,resp))
# call sayHelloAsync which returns Future and we add lambda to print the result when done
self._helloservice.sayHelloAsync(self._name+'Async', self._msg).add_done_callback(lambda f: print('async response: {0}'.format(f.result())))
print("done with sayHelloAsync method")
# call sayHelloAsync which returns Future and we add lambda to print the result when done
self._helloservice.sayHelloPromise(self._name+'Promise', self._msg).add_done_callback(lambda f: print('promise response: {0}'.format(f.result())))
print("done with sayHelloPromise method")



16 changes: 0 additions & 16 deletions samples/rsa/helloimpl.py

This file was deleted.

61 changes: 61 additions & 0 deletions samples/rsa/helloimpl_py4j.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from pelix.ipopo.decorators import ComponentFactory, Provides, Instantiate
from concurrent.futures.thread import ThreadPoolExecutor
@ComponentFactory('helloimpl-provider-factory')
@Provides('org.eclipse.ecf.examples.hello.IHello') # Provides IHello interface as specified by Java interface.
#See <a href="https://github.com/ECF/Py4j-RemoteServicesProvider/blob/master/examples/org.eclipse.ecf.examples.hello/src/org/eclipse/ecf/examples/hello/IHello.java">IHello service interface</a>
@Instantiate('helloimpl-provider-auto', { 'service.exported.interfaces':'*', # Required for export
'service.exported.configs': 'ecf.py4j.host.python', # Required to use py4j python provider for export
'service.intents': ['osgi.async'], # Required to use osgi.async intent
'osgi.basic.timeout':30000}) # Timeout associated with remote calls (in ms)
class PythonHelloImpl(object):
'''
Implementation of Java org.eclipse.ecf.examples.hello.IHello service interface.
This interface declares on normal/synchronous method ('sayHello') and two
async methods as defined by the OSGi Remote Services osgi.async intent. Note
that the service.intents property above includes the 'osgi.async' intent. It
also declares a property 'osgi.basic.timeout' which will be used to assure that
the remote methods timeout after the given number of milliseconds.
See the OSGi Remote Services specification at
https://osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html
The specification defines the standard properties given above.
'''
def sayHello(self, name='Not given', message = 'nothing'):
'''
Synchronous implementation of IHello.sayHello synchronous method. The remote
calling thread will be blocked until this is executed and responds
'''
print("Python.sayHello called by: {0} with message: '{1}'".format(name,message))
return "PythonSync says: Howdy {0} that's a nice runtime you got there".format(name)

def sayHelloAsync(self, name='Not given', message = 'nothing'):
'''
Implementation of IHello.sayHelloAsync. This method will be executed via
some thread, and the remote caller will not block. This method should return
either a String result (since the return type of IHello.sayHelloAsync is
CompletableFuture<String>, OR a Future that returns a python string. In this case,
it returns the string directly.
'''
print("Python.sayHelloAsync called by: {0} with message: '{1}'".format(name,message))
return "PythonAsync says: Howdy {0} that's a nice runtime you got there".format(name)

def _sayHelloFuture(self, name, message):
'''
Function that is executed via a Future in 'sayHelloPromise'.
'''
print("Python._sayHelloFuture called by: {0} with message: '{1}'".format(name,message))
return "PythonFuture says: Howdy {0} that's a nice runtime you got there".format(name)

def sayHelloPromise(self, name='Not given', message = 'nothing'):
'''
This method in IHello java interface has return type Promise<String>. It can either return
a string directly, or return a Future that results in a string. In this case,
a Future is submitted and returned.
'''
# Use thread pool executor
with ThreadPoolExecutor(2) as executor:
# submit self_sayHelloFuture method and return Future
return executor.submit(self._sayHelloFuture, name, message)
File renamed without changes.

0 comments on commit 0549918

Please sign in to comment.