Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into rsa
Browse files Browse the repository at this point in the history
  • Loading branch information
scottslewis committed Apr 27, 2018
2 parents 48679d5 + e9d43a9 commit 8bc965f
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 48 deletions.
8 changes: 5 additions & 3 deletions docs/foreword.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ On March 2015, release 0.6 dropped support for Python 2.6.
Since then, the development slowed down as the core framework is
considered stable.

iPOPO 1.0 should be released mid-2017, when the remote services engine
will be upgraded.
As of 2018, the development of iPOPO is still active.
iPOPO 1.0 will come out when some features, existing or currently in
development, will have been completed, tested and polished.


SOA and SOCM in Python
----------------------
Expand All @@ -75,7 +77,7 @@ The provider or the service itself (they are often the same) must
handle the requirements, *i.e.* looking for the services required to
work and handling their late un/registration.

A component is an object instanciated and handled by an instance
A component is an object instantiated and handled by an instance
manager created by iPOPO.
The manager handles the life cycle of the component, looking for its
dependencies and handling their late registration, unregistration and
Expand Down
32 changes: 18 additions & 14 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ iPOPO depends on only one external library,
`jsonrpclib-pelix <https://github.com/tcalmant/jsonrpclib>`_, which
provides some utility methods and is required to enable remote services.

To install iPOPO, you will need Python 2.7, Python 3.3 or newer.
To install iPOPO, you will need Python 2.7, Python 3.4 or newer.
iPOPO is constantly tested, using Tox and Travis-CI, on the following
interpreters:

* Python 2.7, 3.3, 3.4, 3.5
* Pypy 2 et 3

Support for Python 2.6 has been dropped with iPOPO 0.6. The framework
should run on Python 3.2, but it is not officialy supported.
* Python 2.7
* Python 3.4, 3.5 and 3.6

Support for Python 2.6 has been dropped with iPOPO 0.6.
The framework should run on Python 3.2 and 3.3 and also on Pypy, but this is
not guaranteed. Any feedback on those platforms is welcome.

There are many ways to install iPOPO, so let's have a look to some of
them.
Expand All @@ -29,7 +30,7 @@ environments is recommended to develop your applications.
For a system-wide installation, just run ``pip`` with root privileges::

$ sudo pip install iPOPO

If you don't have root privileges and you can't or don't want to use
virtual environments, you can install iPOPO for your user only::

Expand Down Expand Up @@ -61,8 +62,8 @@ Now you can create a new virtual environment, here called *ipopo-venv*::

Continue to :ref:`then` to activate your new environment.

Previous versions
'''''''''''''''''
Older Python versions
'''''''''''''''''''''

Before Python 3.3, virtual environments were handled by a third-party
package, ``virtualenv``, which must be installed alongside Python.
Expand All @@ -84,7 +85,7 @@ environment::
Installing setuptools, pip............done.

.. _then:

Then...
'''''''

Expand All @@ -97,10 +98,11 @@ If you are a Windows user, the following command is for you::

> ipopo-venv\Scripts\activate

Either way, you show now be using your virtual environment. The shell
prompt should indicate it.
Either way, the ``python`` and ``pip`` commands you type in the shell should
be those of your virtual environment.
The shell prompt indicates the name of the virtual environment currently in use.

Now you can install iPOPO using ``pip``. As this is a virtual
Now you can install iPOPO using ``pip``. As you are in a virtual
environment, you don't need administration rights::

$ pip install iPOPO
Expand All @@ -116,7 +118,7 @@ the following command (both on Linux and Windows)::
Development version
-------------------

If you want to work with latest version of iPOPO, there are two ways:
If you want to work with the latest version of iPOPO, there are two ways:
you can either let ``pip`` pull in the development version, or you can
tell it to operate on a git checkout.
Either way, a virtual environment is recommended.
Expand All @@ -139,3 +141,5 @@ git head as the current version inside the virtual environment.
As the *develop* installation mode uses symbolic links, you simply
have to run ``git pull origin`` to update to the latest version of
iPOPO in your virtual environment.

You can now continue to :ref:`Quickstart`
30 changes: 17 additions & 13 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ help Shows the help
loglevel Prints/Changes the log level
exit Quits the shell (and stops the framework in console UI)
threads Prints the stack trace of all threads
run Runs a shell script
run Runs a Pelix shell script
======== =======================================================

Bundle commands
Expand Down Expand Up @@ -154,7 +154,7 @@ instance Prints the details of a component
waiting Lists the components waiting for an handler
instantiate Starts a new component instance
kill Kills a component
retry Retry the validation of a component
retry Retry the validation of an erroneous component
=========== ============================================

This snippets installs the ``pelix.shell.remote`` bundle and
Expand Down Expand Up @@ -284,11 +284,13 @@ with the various commands described in the :ref:`previous section <quick_shell>`
Uninstalling bundle 12 (provider)...
Component invalidated, the service is gone

Hello from somewhere!
=====================
Hello from somewhere else!
==========================

This section reuses the bundles written in the *Hello World* sample and starts
them into two distinct frameworks. The consumer will use the service provided
from the other framework.

This section reuses the bundles written in the *Hello World* sample, and install
them in two distinct frameworks.
To achieve that, we will use the *Pelix Remote Services*, a set of bundles
intending to share services across multiple Pelix frameworks.
A :ref:`reference card <refcard_remote_services>` provides more information
Expand All @@ -301,11 +303,11 @@ First, we must install the core bundles of the *remote services* implementation:
the *Imports Registry* (``pelix.remote.registry``) and the
*Exports Dispatcher* (``pelix.remote.dispatcher``).
Both handle the description of the shared services, not their link with the
framework: it will be the job of discovery and transport providers.
framework: this will be the job of the discovery and transport providers.
The discovery provider we will use requires to access the content of the
*Exports Dispatcher* of the frameworks it finds, through HTTP requests.
A component, the *dispatcher servlet*, must therefore be instantiate to answer
to those requests::
A component, the *dispatcher servlet*, must be instantiated to answer to those
requests::

bash$ python -m pelix.shell
** Pelix Shell prompt **
Expand Down Expand Up @@ -344,7 +346,7 @@ use a Pelix-specific protocol based on UDP multicast packets.
By default, this protocol uses the UDP port 42000, which must therefore be
accessible on any machine providing or consuming a remote service.

Start two Pelix framework with their shell and, in each one, install the
Start two Pelix frameworks with their shell and, in each one, install the
``pelix.remote.discovery.multicast`` bundle then instantiate the discovery
component::

Expand All @@ -361,10 +363,10 @@ requests and to wait for their responses.
Here, we'll use the JSON-RPC protocol (``pelix.remote.json_rpc``), which is the
easiest to use (*e.g.* XML-RPC has problems handling dictionaries of complex
types).
Transport providers often require to instantiate two components: one for the
export and one for the import.
Transport providers often require to instantiate two components: one handling
the export of services and one handling their import.
This allows to instantiate the export part only, avoiding every single framework
to know about all available services.
to know about all available services::

$ install pelix.remote.json_rpc
Bundle ID: 15
Expand Down Expand Up @@ -426,3 +428,5 @@ use it::

You should then see the greeting message (*Hello, World !*) in the shell of the
provider that has been used by the consumer.

You can now continue to the :ref:`Tutorials`
51 changes: 37 additions & 14 deletions docs/refcards/init_config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ the following entries:
* ``properties`` (optional): a JSON object defining the initial properties of
the component

.. note::

The ``components`` entry requires iPOPO to work.
Therefore, the ``pelix.ipopo.core`` bundle must be declared in the
``bundles`` entry of the initial configuration file.

Here is a sample initial configuration file:

.. code-block:: javascript
Expand All @@ -63,6 +69,7 @@ Here is a sample initial configuration file:
"$new_path/mylib.zip"
],
"bundles": [
"pelix.ipopo.core",
"pelix.misc.log",
"pelix.shell.log",
"pelix.http.basic"
Expand All @@ -78,7 +85,17 @@ Here is a sample initial configuration file:
]
}
Moreover, if the root object contains a ``reset_<name>`` entry, then the
Configuration override
^^^^^^^^^^^^^^^^^^^^^^

The initial configuration can be split in multiple files in order to ease
the specialisation of frameworks sharing a common base configuration.
This is explained in the following `File Lookup`_ section.

Sometimes, it can be necessary to redefine some entries, *e.g* in order to
change a set of components but keeping the bundles to be started.
If the root object contains a ``reset_<name>`` entry, then the
previously loaded configuration for the ``<name>`` entry are forgotten: the
current configuration will replace the old one instead of updating it.

Expand All @@ -88,6 +105,7 @@ For example:
{
"bundles": [
"pelix.ipopo.core",
"pelix.http.basic"
],
"reset_bundles": true
Expand All @@ -101,7 +119,7 @@ configuration files will be cleared and replaced by the one in this file.
File lookup
-----------

A :class:`~InitFileHandler` object updates its internal state with the content
An :class:`~InitFileHandler` object updates its internal state with the content
of the files it parses.
As a result, multiple configuration files can be used to start framework with
a common basic configuration.
Expand All @@ -118,21 +136,21 @@ order:
* ``~`` (user directory)
* ``.`` (current working directory)

When giving a file name to :meth:`~InitFileHandler.load`, the handler
will merge the configuration it contains with its current state.
When giving a file name to :meth:`~InitFileHandler.load`, the handler will
merge the newly loaded configuration with the current state of the handler.

Finally, after having updated a configuration, the :class:`~InitFileHandler`
will remove duplicated in Python path and bundles configurations.
will remove the duplicated elements of the Python path and bundles entries.


Support in Pelix shell
----------------------

The framework doesn't starts a :class:`~InitFileHandler` on its own: it must be
created and loaded before creating the framework.
The framework doesn't start a :class:`~InitFileHandler` on its own: the handler
must be created and loaded before creating the framework.

Currently, only the Pelix Shell Console supports the initial configuration,
using the following arguments:
Currently, all the Pelix Shell interfaces (local console, remote shell and XMPP)
support the initial configuration, using the following arguments:

* *no argument*: the `.pelix.conf` files are loaded as described in
:ref:`init_conf_lookup`.
Expand All @@ -142,9 +160,6 @@ using the following arguments:
* ``-C <filename>``, ``--exclusive-conf <filename>``: only the given
configuration file will be loaded.

It is planned that the support for initial configuration files will be added
to other shells in future iPOPO versions.


API
---
Expand All @@ -153,11 +168,19 @@ API
:members: clear, load, normalize, instantiate_components, bundles,
properties

.. module:: pelix.shell.console

Note that the ``pelix.shell.console`` module provides a
:meth:`~handle_common_arguments` method to automate the use of an
initial configuration with the arguments common to all Pelix Shell scripts:

.. autofunction:: handle_common_arguments

Sample API Usage
----------------

This sample starts a framework based on the default configuration files, plus
a given one named *some_file.json*.
This sample starts a framework based on the default configuration files
(see `File lookup`_), plus a given one named *some_file.json*.

.. code-block:: python
Expand Down
5 changes: 4 additions & 1 deletion docs/tutorials/ipopo_10min.rst
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ service. It contains few English words.

* The ``@Component`` decorator is used to declare an iPOPO component.
It must always be on top of other decorators.
* The ``@Provides`` decorator indicates that the component provides a service.
* The ``@Provides`` decorator indicates that the component provides a service.
* The ``@Instantiate`` decorator instructs iPOPO to automatically create an
instance of our component. The relation between components and instances is
the same than between classes and objects in the object-oriented programming.
Expand Down Expand Up @@ -246,3 +246,6 @@ Here is a sample run, calling ``python main_pelix_launcher.py``:
Bye !
A spell client has been stopped
INFO:pelix.shell.core:Shell services unregistered
You can now go back to see other :ref:`Tutorials` or take a look at the
:ref:`refcards`.
6 changes: 6 additions & 0 deletions pelix/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@
This property is constant during the life of a framework instance.
"""

OSGI_FRAMEWORK_UUID = "org.osgi.framework.uuid"
"""
OSGi standard framework uuid property name. Set in framework init to the value
of FRAMEWORK_UID
"""

# ------------------------------------------------------------------------------

SCOPE_SINGLETON = "singleton"
Expand Down
7 changes: 4 additions & 3 deletions pelix/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
pass

# Pelix beans and constants
from pelix.constants import ACTIVATOR, ACTIVATOR_LEGACY, FRAMEWORK_UID, \
from pelix.constants import ACTIVATOR, ACTIVATOR_LEGACY, FRAMEWORK_UID, OSGI_FRAMEWORK_UUID, \
BundleException, FrameworkException
from pelix.internals.events import BundleEvent, ServiceEvent
from pelix.internals.registry import EventDispatcher, ServiceRegistry, \
Expand Down Expand Up @@ -625,13 +625,14 @@ def __init__(self, properties=None):
# Use a copy of the properties, to avoid external changes
self.__properties = properties.copy()

# Generate a framework instance UUID, if needed
# Generate and set a framework instance UUID, if needed
framework_uid = self.__properties.get(FRAMEWORK_UID)
if not framework_uid:
framework_uid = str(uuid.uuid4())

# Normalize the UID: it must be a string
self.__properties[FRAMEWORK_UID] = str(framework_uid)
# Also normalize the OSGI_FRAMEWORK_UID: it must be a string
self.__properties[OSGI_FRAMEWORK_UUID] = str(framework_uid)

# Properties lock
self.__properties_lock = threading.Lock()
Expand Down

0 comments on commit 8bc965f

Please sign in to comment.