Giter VIP home page Giter VIP logo

ipopo's Introduction

iPOPO logo

iPOPO: A Service-Oriented Component Model for Python

Join the chat at https://gitter.im/tcalmant/ipopo

Latest Version

License

Travis-CI status

Coveralls status

iPOPO is a Python-based Service-Oriented Component Model (SOCM) based on Pelix, a dynamic service platform. They are inspired on two popular Java technologies for the development of long-lived applications: the iPOJO component model and the OSGi Service Platform. iPOPO enables to conceive long-running and modular IT services.

See https://ipopo.readthedocs.io/ for documentation and more information.

Note on this version

This is the 1.x branch of iPOPO, which is intended to work with both Python 2.7 and 3.x.

If you are working with Python 3.7+ and asyncio, you should look at the 2.x branch.

Usage survey

In order to gain insight from the iPOPO community, I've put a really short survey on Google Forms (no login required).

Please, feel free to answer it, the more answers, the better. All feedback is really appreciated.

Install

Option 1: Using pip

iPOPO is available on PyPI and can be installed using pip:

# Install system-wide
$ sudo pip install iPOPO

# ... or user-wide installation
$ pip install --user iPOPO

Option 2: From source

$ git clone https://github.com/tcalmant/ipopo.git
$ cd ipopo
$ python setup.py install

Check install

To check if Pelix is installed correctly, run the following command:

$ python -m pelix.shell --version
Pelix 0.8.0 from /home/tcalmant/git/ipopo/pelix/framework.py

Concepts

Pelix brings the concept of bundle in Python. A bundle is a module with a life cycle: it can be installed, started, stopped, updated and uninstalled.

A bundle can declare a class acting as bundle activator, using the @BundleActivator decorator. This class will be instantiated by the framework and its start() and stop() method will be called to notify the bundle about its activation and deactivation.

When it is active, a bundle can register services. A service is an object implementing a specification and associated to a set of properties. A component will then be able to select and consume a service according to the specification(s) it provides and to its properties.

The components are a concept brought by iPOPO. A component, or component instance, is an object managed by a container. The container handles the interactions between the component and the Pelix framework. That way, the component contains only the code required for its task, not for its bindings with the framework. A component is an instance of a component factory, a class manipulated by iPOPO decorators.

For more information, see the concepts page on the wiki.

Sample

This sample gives a quick overview of the usage of iPOPO. For more information, take a look at iPOPO in 10 minutes.

Service provider

The following code defines a component factory (a class) which instances will provide a sample.hello service.

# iPOPO decorators
from pelix.ipopo.decorators import ComponentFactory, Provides, Instantiate

# Manipulates the class and sets its (unique) factory name
@ComponentFactory("hello-provider-factory")
# Indicate that the components will provide a service
@Provides("sample.hello")
# Tell iPOPO to instantiate a component instance as soon as the file is loaded
@Instantiate("hello-provider-auto")
# A component class must always inherit from object (new-style class)
class HelloProvider(object):
    """
    A sample service provider
    """
    def hello(self, name="world"):
        """
        Says hello
        """
        print("Hello,", name, "!")

    def bye(self, name="cruel world"):
        """
        Says bye
        """
        print("Bye,", name, "!")

When the bundle providing this component factory will be started, iPOPO will automatically instantiate a component, due to the @Instantiate decorator. It is also possible to instantiate a component using shell commands.

Each component instance will provide a sample.hello service, which can be consumed by any bundle or any other component.

Service consumer

The following code defines a component factory (a class) which instances will consume a sample.hello service. If multiple services are available, iPOPO will select the one with the highest rank and the lowest service ID (i.e. the oldest service).

# iPOPO decorators
from pelix.ipopo.decorators import ComponentFactory, Requires, Instantiate, \
    Validate, Invalidate

# Manipulates the class and sets its (unique) factory name
@ComponentFactory("hello-consumer-factory")
# Indicate that the components require a sample.hello service to work
# and to inject the found service in the _svc field
@Requires('_svc', "sample.hello")
# Tell iPOPO to instantiate a component instance as soon as the file is loaded
@Instantiate("hello-consumer-auto")
# A component class must always inherit from object (new-style class)
class HelloConsumer(object):
    """
    A sample service consumer
    """
    def __init__(self):
        """
        Defines (injected) members
        """
        self._svc = None

    @Validate
    def validate(self, context):
        """
        Component validated: all its requirements have been injected
        """
        self._svc.hello("Consumer")

    @Invalidate
    def invalidate(self, context):
        """
        Component invalidated: one of its requirements is going away
        """
        self._svc.bye("Consumer")

When the bundle providing this component factory will be started, iPOPO will automatically instantiate a component, due to the @Instantiate decorator.

Each component instance will require a sample.hello service. Once iPOPO has injected all the required services (here, a single sample.hello service) in a component instance, this instance will be considered valid and iPOPO will call its method decorated by @Validate. There, the component can consume its dependencies, start threads, etc.. It is recommended for this method to start threads and to return quickly, as it blocks iPOPO and the Pelix framework.

When a required service is unregistered by its provider, the component instances consuming it are invalidated. When the method decorated by @Invalidate is called, the service is still injected and should be usable (except for special cases, like remote services).

Run!

To run this sample, you'll need to copy the snippets above in different files:

  • copy the Service provider snippet in a file called provider.py
  • copy the Service consumer snippet in a file called consumer.py

Then, run a Pelix shell in the same folder as those files, and execute the commands listed in this trace:

$ python -m pelix.shell
** Pelix Shell prompt **
$ # Install the bundles
$ install provider
Bundle ID: 11
$ install consumer
Bundle ID: 12
$ # Start the bundles (the order isn't important here)
$ start 11 12
Starting bundle 11 (provider)...
Starting bundle 12 (consumer)...
Hello, Consumer !
$ # View iPOPO instances
$ instances
+----------------------+------------------------------+-------+
|         Name         |           Factory            | State |
+======================+==============================+=======+
| hello-consumer-auto  | hello-consumer-factory       | VALID |
+----------------------+------------------------------+-------+
| hello-provider-auto  | hello-provider-factory       | VALID |
+----------------------+------------------------------+-------+
| ipopo-shell-commands | ipopo-shell-commands-factory | VALID |
+----------------------+------------------------------+-------+
3 components running
$ # View details about the consumer
$ instance hello-consumer-auto
Name.....: hello-consumer-auto
Factory..: hello-consumer-factory
Bundle ID: 12
State....: VALID
Services.:
Dependencies:
        Field: _svc
                Specification: sample.hello
                Filter......: None
                Optional.....: False
                Aggregate....: False
                Handler......: SimpleDependency
                Bindings:
                        ServiceReference(ID=11, Bundle=11, Specs=['sample.hello'])
Properties:
        +---------------+---------------------+
        |      Key      |        Value        |
        +===============+=====================+
        | instance.name | hello-consumer-auto |
        +---------------+---------------------+

$ # Modify the provider file (e.g. change the 'Hello' string by 'Hi')
$ # Update the provider bundle (ID: 11)
$ update 11
Updating bundle 11 (provider)...
Bye, Consumer !
Hi, Consumer !
$ # Play with other commands (see help)

First, the install commands are used to install the bundle: they will be imported but their activator won't be called. If this command fails, the bundle is not installed and is not referenced by the framework.

If the installation succeeded, the bundle can be started: it's activator is called (if any). Then, iPOPO detects the component factories provided by the bundle and instantiates the components declared using the @Instantiate decorator.

The instances and instance commands can be use to print the state and bindings of the components. Some other commands are very useful, like sl and sd to list the registered services and print their details. Use the help command to see which ones can be used.

The last part of the trace shows what happens when updating a bundle. First, update the source code of the provider bundle, e.g. by changing the string it prints in the hello() method. Then, tell the framework to update the bundle using the update command. This command requires a bundle ID, which has been given as a result of the install command and can be found using bl.

When updating a bundle, the framework stops it and reloads it (using imp.reload). If the update fails, the old version is kept. If the bundle was active before the update, it is restarted by the framework.

Stopping a bundle causes iPOPO to kill the component instance(s) of the factories it provided. Therefore, no one provides the sample.hello service, which causes the consumer component to be invalidated. When the provider bundle is restarted, a new provider component is instantiated and its service is injected in the consumer, which becomes valid again.

Batteries included

Pelix/iPOPO comes with some useful services:

  • Pelix Shell: a simple shell to control the framework (manage bundles, show the state of components, ...). The shell is split in 5 parts:

    • the parser: a shell interpreter class, which can be reused to create other shells (with a basic support of variables);
    • the shell core service: callable from any bundle, it executes the given command lines;
    • the UIs: text UI (console) and remote shell (TCP/TLS, XMPP)
    • the commands providers: iPOPO commands, report, EventAdmin, ...
    • the completion providers: Pelix, iPOPO

    See the shell tutorial for more information.

  • An HTTP service, based on the HTTP server from the standard library. It provides the concept of servlet, borrowed from Java.

    See the HTTP service reference for more information.

    There is also a routing utility class, based on decorators, which eases the development of REST-like servlets.

  • Remote Services: export and import services to/from other Pelix framework or event Java OSGi frameworks!

    See the remote services reference for more information.

Pelix also provides an implementation of the EventAdmin service, inspired from the OSGi specification.

Feedback

Feel free to send feedback on your experience of Pelix/iPOPO, via the mailing lists:

Bugs and features requests can be submitted using the Issue Tracker on GitHub.

Contributing

All contributions are welcome!

  1. Create an issue to discuss about your idea or the problem you encounter
  2. Fork the project
  3. Develop your changes
  4. Check your code with pylint and pep8
  5. If necessary, write some unit tests
  6. Commit your changes, indicating in each commit a reference to the issue you're working on
  7. Push the commits on your repository
  8. Create a Pull Request
  9. Enjoy!

Please note that your contributions will be released under the project's license, which is the Apache Software License 2.0.

Compatibility

Pelix and iPOPO are tested using Travis-CI with Python 2.7 and 3.4 to 3.6. Pypy is not tested anymore due to various bugs during tests setup.

iPOPO doesn't support Python 2.6 anymore (since version 0.5.6).

License

iPOPO is released under the Apache Software License 2.0.

ipopo's People

Contributors

elrhedda avatar gitter-badger avatar matthieucan avatar scottslewis avatar tcalmant avatar trellixvulnteam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ipopo's Issues

Factory warning still present after correction + update

$ install cohorte.vote.dummy_store
Bundle ID: 55
$ start 55
2014-09-11 16:21:11,445:ERROR   :ipopo.core          : Cannot register factory 'VoteChartServletFactory' of bundle 55 (cohorte.vote.dummy_store): 'VoteChartServletFactory' factory already exist
$ update 55
2014-09-11 16:21:42,072:ERROR   :ipopo.core          : Cannot register factory 'VoteChartServletFactory' of bundle 55 (cohorte.vote.dummy_store): 'VoteChartServletFactory' factory already exist
$ update 55
2014-09-11 16:21:44,201:ERROR   :ipopo.core          : Cannot register factory 'VoteChartServletFactory' of bundle 55 (cohorte.vote.dummy_store): 'VoteChartServletFactory' factory already exist
$ stop 55
$ update 55
$ start 55
2014-09-11 16:21:51,133:ERROR   :ipopo.core          : Cannot register factory 'VoteChartServletFactory' of bundle 55 (cohorte.vote.dummy_store): 'VoteChartServletFactory' factory already exist

Normalize HTTP server port in its validate() method

When instantiating an HTTP service component using the instantiate shell command, the port property must be converted to an integer, else Python 3 fails with the error below.
Also, the invalidate method must be protected to avoid using a None reference.

$ instantiate pelix.http.service.basic.factory httpd pelix.http.port=9000
Component 'httpd' : error calling callback method for event VALIDATE
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\pelix\ipopo\instance.py", line 522, in safe_callback
    return self.__callback(event, *args, **kwargs)
  File "C:\Python34\lib\site-packages\pelix\ipopo\instance.py", line 472, in __callback
    result = comp_callback(self.instance, *args, **kwargs)
  File "C:\Python34\lib\site-packages\pelix\http\basic.py", line 796, in validate
    if self._port is None or self._port < 0:
TypeError: unorderable types: str() < int()
Component 'httpd' : error calling callback method for event INVALIDATE
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\pelix\ipopo\instance.py", line 522, in safe_callback
    return self.__callback(event, *args, **kwargs)
  File "C:\Python34\lib\site-packages\pelix\ipopo\instance.py", line 472, in __callback
    result = comp_callback(self.instance, *args, **kwargs)
  File "C:\Python34\lib\site-packages\pelix\http\basic.py", line 867, in invalidate
    self._server.shutdown()
AttributeError: 'NoneType' object has no attribute 'shutdown'
Component 'httpd' instantiated.

Create a @Singleton iPOPO decorator

Add a decorator replacing either @ComponentFactory or @Instantiate, to ensure that one and only one component from this factory is instantiated at a time.

Shell command "threads" doesn't work in Jython

sys._current_frames() is not available in Jython, therefore threads and thread shell commands fail.

$ threads
ERROR:pelix.shell.core:Error calling default.threads: '<reflected field public org.python.core.PyObject o' object has no attribute '_current_frames'
Traceback (most recent call last):
  File "C:\jython2.7b3\Lib\site-packages\pelix\shell\core.py", line 703, in execute
    result = method(io_handler, *args, **kwargs)
  File "C:\jython2.7b3\Lib\site-packages\pelix\shell\core.py", line 1152, in threads_list
    frames = sys._current_frames()
AttributeError: '<reflected field public org.python.core.PyObject o' object has no attribute '_current_frames'

Accept variables in @Requires and requires.filter

When using a filter in @Requires, it would be interesting to have use a property variable to have an instance-dependent filter.

Something like:

@ComponentFactory()
@Property('_prop_field', 'my.property')
@Requires('_dependency', 'dep_spec', ldap_filter="(svc.value=${my.property})")
...

Shell Console stops Pelix when running as daemon

If a Pelix framework is started using start-stop-daemon with the pelix.shell.console bundle, the latter stops the framework immediately as it detects an EOF in the standard input.

The bundle should at least check if it is run as a daemon or log a warning before stopping the framework.

Handle ServiceFactory-like capacities

When calling BundleContext.getService(ref), where ref is a ServiceReference to a service factory, then the framework should return the result of the get_service() method of this factory.
(See the OSGi specification for more information on this concept : http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/ServiceFactory.html).

In Pelix, this could be implemented by using a pelix.service.factory service property, and by modifying the API :

  • get_service_reference(clazz, ldap_filter, prefer_factories=False):

    if prefer_factories is True, services factories are sorted separately and placed at the beginning of the result list.

  • get_service(reference, factoryParameters=None):

    if the given reference points to a service factory, then the given parameters will be forwarded to its get_service() method; else the second argument will be ignored.

Enhance bundle concept

Pelix should override the import method when installing a bundle, in order to avoid duplicated imports and to have a better control on the Python path.

The code could be inspired of the "exocet" project (https://launchpad.net/exocet/).

Add a MQTT Remote Services Discovery provider

Implement a Remote Service Discovery provider, which could work as a centralized discovery protocol.

It would also be interesting to try to implement a JSON-RPC-like transport through MQTT.

Create a @Temporal handler

It should act like the @Temporal handler of iPOJO.

It has the same signature as @requires, but it behaves differently: when calling a dependency that has disappeared, the called will be paused until a new dependency is injected or a timeout exception will be raised.

Support new remote services control properties

Currently, Pelix Remote Services supports the pelix.remote.export.reject property to reject the export of a specific interface when using remote services, even if it has been indicated in the service.exported.interfaces property.

The main use case is when a component provides multiple services but disallows the export of only some of them, like local-only services (shell commands, ...).
This is useful when a component is instantiated manually, with the services.exported.interfaces property set to * (all).

Two other properties should be defined to ease the description of those constraints:

  • pelix.remote.export.none: no export is allowed for this component, even if the instantiator says otherwise.
  • pelix.remote.export.only: this is the opposite of reject. Only interfaces listed in this property can be exported.

pelix.remote.export.none is the top-priority property: when set all others are ignored.
If both export.onlyand export.reject properties are set, the exported interfaces those in export.only minus those of export.reject.
if the result is an empty set, then the export is aborted.

Possible bug in ConfigurationAdmin

It seems that the https://github.com/tcalmant/demo-ipopo-nao project has problems with the MQTT configuration process, based on ConfigurationAdmin.

The demo fails to start because the MQTT component is not configured.
The configuration admin service prints the following line:
PID error: mqtt-connector -- <internals.mqtt.MqttConnector object at ...>

Implement an HTTP Service based on Tornado

It seems possible to implement an HTTP service using Tornado.
This should increase the performances of Pelix HTTP (Tornado is faster than the HTTP server from the standard library).
It should also bring new features like websockets support.

An experimental implementation could be written before the release of 0.6.3.

Optimize handlers selection during callbacks

When a handler event occurs, e.g. when a controller changes state, all the handlers are called back, whereas only those of "service_provider" kind should.

Proposal: the StoredInstance.__safe_handlers_callback() method should have the target "kind" as first parameter to select those specific handlers.
If this kind is None, then all handlers must be notified.

Create a @RequiresBest handler

Same as @requires for single (non-aggregate) dependencies, but ensures that the injected service will always be the "best" one, according to service ranking and registration orders.

The injected service will always be the one with the highest ranking (greatest service ranking integer).

Implement basic RemoteServices

Implement a basic support for XML-RPC (using xmlrpclib) and JSON-RPC (using jsonrpclib or a fork) for exported services, i.e. with the service.exported property.

The implementations might be provided as servlets for the HTTP service.

Support arguments in pelix.shell.console

pelix.shell.console is the script executed by most of Pelix/iPOPO users to quickly test their bundles/
Therefore it should accept some arguments to ease those tests.

Here are some ideas:

  • --version: prints the version of Pelix and its installation folder, then quits returning 0;
  • --init <script>: runs the given script file (in fact, calls run <file>) before accepting shell input;
  • --run <script>: runs the given script file then exits;

Support ExportEndpoint replacement by name

When an exported service is unregistered or when its endpoint name is updated, the dispatcher should look for services which export was refused due to an endpoint name conflict.
For example, if a service S1 and a service S2 require the endpoint name E1, S2 must be exported with this name as soon as S1 is unregistered or requires another endpoint name.

Provide more tests

Increase the number and the quality of unit tests.
Mainly on Pelix service handling and on dependency injection.

Content-type sent

In pelix.http.__init__.py , if no meme-type is given to the function send_content, the content-type of the response will always be sent with the value text/html.

def send_content(self, http_code, content, mime_type="text/html", http_message=None, content_length=-1):
    ...
    self.set_response(http_code, http_message)
    if mime_type:
        self.set_header("content-type", mime_type)
    ...

So if it was set prior to the call of that function, the value will be overriden.

Speed up the LDAP Filter implementation

The LDAP Filter module (pelix/ldapfilter.py) is the slowest part of the code of iPOPO.
As it is often used, mainly for service filtering, it should be way faster.

According to line profiling, the evaluation of an LDAP filter takes more than 70% of the call time when using the get_service_references() method.

Create a @PostRegistration callback

The @PostRegistration decorated method would be called right after a service has been registered by the @Provides handler.
This would allow to configure the component in @Validate, to register the service, then to start threads/handlers which require that the services to be provided.

Add a report shell command

A report shell command could be used to generate a full report of the current state of the framework, containing:

  • OS description (using os.name and the platform module)
  • Python description (version, path to the interpreter)
  • Current state of Pelix (list installed bundles, with state, version and path)
  • Current state of iPOPO (list of instances, with factory name, instance name and source bundle)
  • Memory consumption (if possible)

The report might be generated for different levels of information (e.g. small, framework, memory, full, ...).
The generated report might written to the standard output or to a file. It could also be sent through a HTTP POST request or via an email (configuration to be specified...)

Remove support of Python 2.6

Support for Python 2.6 forces to use ugly tricks to ensure compatibility with this version.
It also causes a lot of trouble to correct bugs, as each correction must then be rewritten to work with Python 2.6.

Update the web site

  • Update the tutorials, according to the new API and capacities
  • Add a page about Pelix and iPOPO internals (for developers)

Add a no_restart flag to @Requires

In most cases, it is acceptable to replace an injected service with a new one without restarting the client component.
For example, C depends on a service provided by A and B, and A is injected in C.
When A is invalidated, B could be immediately injected in C, without invalidating C.

Redefine the MQTT service

The MQTT service provided by pelix.services.mqtt is not really usable as is.
Its API must be redefined in order to support real use cases or it will be removed.

It should also use the MQTT client class instead of having a parallel implementation.

Release 0.5.6

Feature release of iPOPO

  • New Remote Services implementation, closer to the OSGi specification and compatible with ECF (with mDNS and Jabsorb-RPC)
  • New iPOPO "Waiting List" service, instantiating components as soon as their factories appear
  • New iPOPO handler @RequiresMap
  • First implementation of an MQTT client service
  • New @BundleActivator decorator for Pelix bundles
  • Bug fixes in both Pelix and iPOPO

Try to optimize aggregated dependencies

The @Requires injects lists in instances when working with aggregated dependencies.
When a new dependency is found, it is appended to the list, which therefore not sorted according to service ranking, but keeps item in place.

We should check if using collections.deque would be more efficient, as it is optimized for right-append operations.

Erroneous component shouldn't stay in validating/invalidating modes

If an exception is raised during a call to the methods decorated with @Validate or @Invalidate, the state seen by iPOPO is kept as is, i.e. "Validating" or "Invalidating".

These components should be considered in either an "invalid" or "error" state, to reflect the problem.

socket has no attribute 'IPPROTO_IPV6' on Windows

When trying to start the Remote Shell on Windows, the following error occurs:

ERROR:InstanceManager-rshell:Component 'rshell' : error calling callback method for event VALIDATE
Traceback (most recent call last):
  File "C:\Users\Thomas Calmant\Programmation\git\ipopo\pelix\ipopo\instance.py", line 507, in __safe_callback
    return self.__callback(event, *args, **kwargs)
  File "C:\Users\Thomas Calmant\Programmation\git\ipopo\pelix\ipopo\instance.py", line 455, in __callback
    result = comp_callback(self.instance, *args, **kwargs)
  File "C:\Users\Thomas Calmant\Programmation\git\ipopo\pelix\shell\remote.py", line 359, in validate
    _create_server(self, self._address, self._port)
  File "C:\Users\Thomas Calmant\Programmation\git\ipopo\pelix\shell\remote.py", line 249, in _create_server
    server = ThreadingTCPServerFamily((server_address, port), request_handler)
  File "C:\Users\Thomas Calmant\Programmation\git\ipopo\pelix\shell\remote.py", line 228, in __init__
    self.socket.setsockopt(socket.IPPROTO_IPV6, opt_ipv6_only, 0)
AttributeError: 'module' object has no attribute 'IPPROTO_IPV6'

HTTP Servlet binding acceptance should be tested before the availability of the path

When two servlets services are to be bound on a same path but on two different HTTP services, the bound_to() method is not sufficient to have a clean behaviour: an exception will be raised when the second servlet path will be tested.

The solution could be:
1/ let the servlet register itself in the bound_to() method, if it accepts the server description
2/ let the servlet implement a new method (e.g. accept_server()), called before the servlet path check.

Dynamic/plugged in handlers

iPOPO should support a new kind of handlers, which could be added to live instance managers at runtime.
There activation couid be requested in two ways:

  • the component indicates that it accepts to be handled by an optional handler: if it's here, the handler is bound to the component, else the component is started as normal.
  • the handler indicates the components it wants to be bound to.

The idea is to enable optional non-functional properties handling using iPOPO handlers.
For example, the logger sample handler could be enabled for all components as soon as its bundle is started, but it must not prevent the instantiation of components if it is absent.

As they can be enabled after the instantiation of the component, and event after its validation, those handlers should not be able to manipulate the component.

Add a "Remote Framework Directory"

Prepare a directory associating a framework UID with its host address.

That way, a discovery protocol will be able to send multiple host addresses to access the framework, and the "Framework Directory" will select the first working one or the last one used.

This shall allow to use the MQTT discovery with protocols other than MQTT-RPC.

Pelix can't uninstall bundles without parent package (i.e. simple files)

Shell sample:

$ install pelix_boot                                                                           
Bundle ID: 12                                                                                  
$ uninstall 12                                                                                 
Uninstalling bundle 12...                                                                      
ERROR:pelix.shell.core:Error calling default.uninstall: need more than 1 value to unpack       
Traceback (most recent call last):                                                             
  File "c:\users\thomas\documents\git\ipopo\pelix\shell\core.py", line 604, in execute         
    result = method(session, *args, **kwargs)                                                  
  File "c:\users\thomas\documents\git\ipopo\pelix\shell\core.py", line 1381, in uninstall      
    bundle.uninstall()                                                                         
  File "c:\users\thomas\documents\git\ipopo\pelix\framework.py", line 423, in uninstall        
    self.__framework.uninstall_bundle(self)                                                    
  File "c:\users\thomas\documents\git\ipopo\pelix\framework.py", line 1098, in uninstall_bundle
    parent, basename = name.rsplit('.', 1)                                                     
ValueError: need more than 1 value to unpack                                                   

Increase compatibility for IronPython

It seems that the "try-except ImportError" trick to have a code working with both Python 2 and Python 3 doesn't work well with IronPython.

It seems the except block should intercept both ImportError and AttributeError exceptions, as shows this trace, running "run_remote.py" :

Traceback (most recent call last):
  File "C:\Program Files (x86)\IronPython 2.7\Lib\importlib\__init__.py", line 37, in import_module
  File "run_remote.py", line 316, in <module>
  File "run_remote.py", line 203, in main
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\pelix\framework.py", line 1528, in create_framework
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\pelix\framework.py", line 1337, in install_bundle
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\pelix\framework.py", line 728, in install_bundle
  File "C:\Program Files (x86)\IronPython 2.7\lib\site-packages\pelix\remote\dispatcher.py", line 60, in <module>
AttributeError: 'LightException' object has no attribute 'client'

Make the RemoteServices package closer to OSGi specifications

Current implementation only took into account part of the Remote Services specification (Chapter 100 of OSGi Compendium Specifications).

A new iteration should be made to comply with both Remote Services and Remote Services Admin specifications (Chapter 122).

Update Documentation

Update the documentation and tutorials at https://ipopo.coderxpress.net/

  • Update docs & tutorials with the new APIs (@BundleActivator, iPOPO waiting list, ...)
  • Tutorials for new services (MQTT, ConfigAdmin, ...)
  • Rewrite the Eclipse IoT day page: link to code, Youtube videos, ...
  • Review pages style

Update .coveragerc file

The options of .coveragerc have changed with coverage 4.0.
The exclude option seems to have been renamed:

py27 installed: coverage==4.0,iPOPO==0.6.3,jsonrpclib-pelix==0.2.6,nose==1.3.7,wheel==0.24.0
[...]
coverage.misc.CoverageException: Unrecognized option '[report] exclude=' in config file .coveragerc

This causes Travis-CI builds to fail.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.