Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Projet de fin d'études Gestion de ressources en environnement pervasif
Brice Chardin DPt. Télécommunications Services & Usages 23/06/2008
Encadrants : Frédérique Laforest
Jean-Marc Petit Yann Gripay
i
Remerciements
Je remercie les membres de l'équipe SIP et du LIRIS que j'ai eu l'occasion de rencontrer au cours de
ce PFE. En particulier :
Mes encadrants Yann Gripay, Frédérique Laforest et Jean-Marc Petit, pour l'aide et les nombreux
conseils qu'ils m'ont donnés tout au long de ce projet.
Liya Zeng pour le travail effectué lors de son projet de fin d'étude, dont je me suis inspiré.
Les personnes avec qui j'ai partagé le bureau : Romain Cuenot, Eric Dubreuil, Quang-Trung Nguyen,
Ny Haingo Andrianarisoa, Romuald Thion et Julien Gossa pour l'ambiance conviviale qui y régnait.
ii
Table des matières
1 Introduction ..................................................................................................................................... 1
1.1 Contexte .................................................................................................................................. 1
1.2 Le projet SoCQ ......................................................................................................................... 1
1.3 Le PFE....................................................................................................................................... 3
2 Analyse du cahier des charges ........................................................................................................ 4
2.1 Architecture ............................................................................................................................. 4
2.2 Choix des technologies et des outils ....................................................................................... 5
2.2.1 UPnP ................................................................................................................................ 5
2.2.2 OSGi & Felix ..................................................................................................................... 5
2.2.3 Maven .............................................................................................................................. 5
2.2.4 Eclipse .............................................................................................................................. 6
2.3 Organisation ............................................................................................................................ 6
3 Gestion des ressources .................................................................................................................... 7
3.1 Objectifs................................................................................................................................... 7
3.2 Architecture ............................................................................................................................. 7
3.3 Service SoCQ ............................................................................................................................ 8
3.4 Gestionnaires de ressources locaux ........................................................................................ 8
3.5 Gestionnaire de ressources global ........................................................................................ 10
3.6 Contrôleur du gestionnaire de ressources global ................................................................. 11
3.7 Conclusion ............................................................................................................................. 13
4 Gestion des tables ......................................................................................................................... 14
4.1 Objectifs................................................................................................................................. 14
4.2 Architecture ........................................................................................................................... 14
4.3 Gestionnaire de tables .......................................................................................................... 15
4.3.1 Catalogue ....................................................................................................................... 17
4.3.2 Tables ............................................................................................................................. 17
4.3.3 TableProxy ..................................................................................................................... 18
4.3.4 Objets Future ................................................................................................................. 18
4.3.5 Commandes ................................................................................................................... 18
4.3.6 Binding Patterns ............................................................................................................ 20
4.3.7 Gestionnaire de listes de services ................................................................................. 20
4.4 Contrôleur de tables .............................................................................................................. 21
4.5 Conclusion ............................................................................................................................. 23
5 Expérimentations .......................................................................................................................... 24
6 Conclusion ..................................................................................................................................... 28
7 References ..................................................................................................................................... 29
8 Annexes ......................................................................................................................................... 30
8.1 Interface ISoCQService .......................................................................................................... 30
8.2 Classe SoCQServiceDescription ............................................................................................. 31
8.3 Classe Tuples ......................................................................................................................... 32
8.4 Spécifications UPnP pour la gestion des ressources ............................................................. 33
1
1 Introduction
1.1 Contexte
Les environnements informatiques tendent à évoluer vers ce qu'on appelle des systèmes pervasifs [1]. Contrairement à l'utilisation contemporaine de l'informatique où l'utilisateur interagit consciemment avec un appareil dans un but précis, un système pervasif implique plusieurs dispositifs informatiques, sans nécessairement que l'utilisateur en ait conscience. Ces systèmes, généralement destiné à des applications de la vie quotidienne, incluent de petits et peu coûteux dispositifs de traitement en réseau, intégrés et distribués dans l'environnement.
L'axe Systèmes d'information communicants du Laboratoire d'InfoRmatique en Image et Systèmes d'information (LIRIS) possède une équipe traitant de ces systèmes pervasifs : l'équipe SIP (Systèmes d'Information Pervasifs). Un des projets de cette équipe s'intéresse à obtenir une vision homogène des services et des données. Il s'agit du projet SoCQ : Service-oriented Continuous Queries [2,3,4].
1.2 Le projet SoCQ
Le projet SoCQ a pour objectif de proposer un cadre (framework) permettant de faciliter le développement d'applications dans un environnement pervasif. En adoptant une approche inspirée des bases de données, ce framework donne une représentation homogène des sources de données hétérogènes de l'environnement. Ces sources de données, qui peuvent être des relations dynamiques, des flux de données ou des services, sont représentées sous forme de tables relationnelles. Les applications utilisant ce framework sont alors définies avec un langage de type SQL.
Pour illustrer le fonctionnement de SoCQ, on considère un scénario simple de surveillance de
températures dans différentes zones. Ce scénario implique les ressources suivantes : des capteurs de
température qui fournissent un flux de valeurs de température relevées dans différents lieux, et un
service d'envoi de messages instantanés.
La traduction de ce scénario pour SoCQ se compose de deux éléments : la description des ressources
(catalogue) et la description de l'application (requête). Le catalogue est un ensemble de tables, qui
correspondent à des relations (RELATION) ou des flux (STREAM)
La description des ressources de ce scénario dans un langage de description de données est la
suivante :
CREATE STREAM Temperature (
Area CHAR,
Temperature REAL
)
CREATE RELATION Employee (
Name STRING(20),
Address STRING(50),
Messenger SERVICE,
Message STRING(20) VIRTUAL,
Sent CHAR VIRTUAL
)
2
CREATE RELATION Surveillance (
Area CHAR,
Manager STRING(20),
Threshold REAL,
AlertMessage STRING(20)
)
On remarque un style similaire aux create de tables en SQL classique. Néanmoins, deux notions
nouvelles apparaissent :
- Les STREAM
Température représente le flux de températures provenant des différents capteurs répartis dans
l'environnement. Il contient les localisations des capteurs (Area) et les valeurs des températures
(Temperature). Contrairement à une relation, les tables de type flux ne stockent pas les données.
- Les attributs VIRTUAL et SERVICE
Employee est une table relationnelle contenant des attributs virtuels. Ces attributs n'auront de
valeur attribuée qu'au cours du traitement de la requête. Elle contient les noms des employés
(Name), leurs adresses de messagerie (Address), l'identifiant du service de messagerie à utiliser
(Messenger), qui est un attribut de type servcie, et deux attributs virtuels correspondant au message
à envoyer (Message) et à la confirmation de l'envoi du message (Sent).
Surveillance est une table relationnelle classique dont chaque occurrence décrit une localisation à
surveiller (Area), le nom du responsable de la zone (Manager), le seuil de température (Threshold) et
le message d'alerte à envoyer (AlertMessage).
Dans ce scénario, on souhaite envoyer un message au responsable d'une zone lorsque la
température dans celle-ci dépasse un certain seuil. La requête SoCQ permettant de répondre à ce
besoin est la suivante :
SELECT Area, Manager, Threshold, Temperature, Sent
FROM Temperature T, Surveillance S, Employee E
WHERE S.Manager = E.Name
AND S.Area = T.Area
AND S.Threshold < T.Temperature
AND E.Message = S.AlertMessage
SoCQ compare en continu les températures, arrivant sur le flux, avec les seuils enregistrés dans la
relation Surveillance. Si les valeurs sont supérieures aux seuils, SoCQ fait appel au service de
messagerie pour envoyer le message correspondant.
Le moteur d'exécution de requêtes SoCQ est développé parallèlement par l'équipe SoCQ, et est
utilisé pour certains tests (voir section 5).
Par ce langage déclaratif de haut niveau, SoCQ permet de faciliter le développement d'application
pervasives. Au lieu d'écrire du code Java spécifique, le développeur peut se concentrer sur
l'application.
3
1.3 Le PFE
Ce projet de fin d'études "Gestion de ressources en environnement pervasif" s'intègre dans le projet
SoCQ. Ce PFE a pour but de fournir une gestion de ressources pour tester et évaluer l'outil SoCQ. Cela
se décompose en plusieurs parties :
- Définir un modèle de service pour le système SoCQ.
- Effectuer la liaison entre les tables et les services.
- Gérer des tables relationnelles étendues avec les services, en vue d'une utilisation par le
moteur d'exécution de requêtes SoCQ.
- Implémenter et tester le système.
Ce projet constitue une brique nécessaire au fonctionnement du projet SoCQ. Il permet de simplifier
le développement du moteur SoCQ, mais également des services fournis par les différents éléments
du système pervasif associé.
Le travail demandé comprend la rédaction de spécifications, le développement et le test de la
gestion de tables, de la gestion de ressources et de quelques services, notamment ceux impliqués par
le scénario présenté dans la section 1.2.
4
2 Analyse du cahier des charges
2.1 Architecture
L'architecture de ce projet (voir fig.1) est composée de deux parties. La première s'occupe de la
gestion des ressources, tandis que la deuxième concerne la gestion du catalogue de tables mis à
disposition du moteur SoCQ
Les ressources pouvant être réparties sur le réseau, cette deuxième partie est également composée
de deux sous-parties : un gestionnaire de ressources global, centralisé, et un ou plusieurs
gestionnaires de ressources locaux.
Fig.1 : Architecture globale de l'outil SoCQ
Un service au sens SoCQ est une entité externe possédant des méthodes, des flux et des propriétés.
Cette entité peut être le service lui-même, ou servir de proxy pour un service externe. Par exemple,
le scénario de surveillance de température utilise deux services : un service de capture de
5
température qui gère un capteur branché sur la même machine, et un service de messagerie qui sert
de proxy, communiquant avec le serveur de messagerie.
Les gestionnaires des ressources locaux s'occupent de la découverte de services au niveau local et de
la mise à disposition de ces services pour le gestionnaire de ressources global.
Le gestionnaire de ressources global met à disposition du gestionnaire de tables l'ensemble des
ressources du système, en masquant les problèmes réseaux. Il s'occupe de la découverte et de
l'invocation à distance. Ce gestionnaire de ressources est associé à un contrôleur servant à visualiser
et tester les services. Ce contrôleur de ressources n'est pas nécessaire au bon fonctionnement du
système.
Le moteur SoCQ sert à exécuter les requêtes fournies par un développeur d'applications pervasives. Il
a pour cela besoin du gestionnaire de tables, qui lui propose un ensemble de tables relationnelles (le
catalogue), et sert d'intermédiaire avec le gestionnaire de ressources global. Un contrôleur de tables
est associé au gestionnaire de tables. Il permet l'administration du catalogue du gestionnaire de
tables.
2.2 Choix des technologies et des outils
2.2.1 UPnP
Le protocole réseau utilisé pour la gestion des ressources dans ce PFE est UPnP [6]. En effet, les
systèmes pervasifs utilisant de nombreux dispositifs de traitement en réseau, UPnP permet la
découverte automatique de ces éléments, ainsi que l'invocation à distance des méthodes proposés
par les services. De plus, ce protocole permet la notification d'évènements, utilisé pour les flux de
données.
Il aurait également été possible d'utiliser RMI [7] ou CORBA [8], mais UPnP permet la découverte
automatique, ce qui simplifie le développement de la partie réseau du gestionnaire de ressources. Ce
protocole est de plus indépendant du langage de développement.
2.2.2 OSGi & Felix
OSGi [7] est un ensemble de spécifications pour une plateforme de déploiement et d'exécution pour
les applications Java. OSGi fournit une architecture orientée services permettant aux composants de
se découvrir entre eux dynamiquement. Les applications peuvent alors être composées de
composants réutilisables et coopératifs appelés bundles, qui sont des archives Java avec des
métadonnées spécifiques.
Apache Felix [9] est une implémentation open-source du framework OSGi et d'une partie des
services standards selon la spécification OSGi R4. Un de ces services standards, UPnP Service, permet
de faire le lien entre un périphérique UPnP et le registre de services OSGi, notamment en gérant les
dépendances entre bundles, ce qui facilite le développement du gestionnaire de ressources pour le
projet SoCQ.
2.2.3 Maven
Maven [10] est un outil open-source de complilation pour les projets Java. Maven utilise une
approche déclarative, où le contenu et la structure du projet sont décrits par un Project Object
6
Model (POM). Maven permet en particulier d'obtenir facilement des bundles OSGi, c'est la raison
pour laquelle cet outil est utilisé pour ce projet.
2.2.4 Eclipse
Eclipse IDE [11] est un environnement de développement libre. Grâce à son architecture développée
autour de la notion de plugins, Maven et Felix peuvent être intégrés à l'IDE, ce qui facilite le
développement et débogage des bundles.
2.3 Organisation
Ce projet de fin d'études dure un total de dix semaines et demie. L'organisation du travail est
présentée dans le tableau suivant :
S14 S15 S16 S17 S18 S19 S20 S21 S22 S23 S24 S25 S26
Imprégnation du sujet et lecture de documentations
Conception des gestionnaires de ressource
Développement et tests des gestionnaires de ressource
Conception du gestionnaire de tables
Développement et tests du gestionnaire de tables
Rédaction du mémoire
Préparation de la soutenance et Packaging
Soutenance
Les livrables sont :
- Les spécifications du gestionnaire de ressources, fin semaine 16.
- Les sources du gestionnaire de ressources, fin semaine 19.
- Les spécifications du gestionnaire de tables, fin semaine 21.
- Les sources du gestionnaire de tables, fin semaine 23.
Cependant, la plupart des livrables, notamment les spécifications, ont évolué en fonction des
remarques des encadrants grâce à des réunions hebdomadaires, et ont été livrés en version finale
après les dates prévues initialement.
Une première présentation du gestionnaire de ressources a été effectuée au milieu de la semaine 19.
Des pré-soutenances sont également prévues en début de semaine 26.
7
3 Gestion des ressources
3.1 Objectifs
Les services étant répartis dans l'environnement, le rôle des gestionnaires de ressources est de
centraliser l'accès à ces services pour que le gestionnaire de tables s'affranchisse des problèmes
réseau.
3.2 Architecture
La découverte de services par les gestionnaires de ressources locaux s'effectue au niveau d'OSGi,
chaque service doit donc proposer un proxy ou bien être lui-même sous forme d'un bundle OSGi
(voir exemple fig.2).
Fig.2 : illustration de l'architecture choisie pour la gestion de ressources
8
3.3 Service SoCQ
Un service au sens SoCQ est une entité possédant des méthodes, des flux et des propriétés. Tout service doit implémenter l'interface ISoCQService (voir annexe 1) et ainsi permettre de récupérer sa description (voir annexe 2), de s'abonner/désabonner à ses flux et d'invoquer ses méthodes.
Exemples :
Le service de température et le service de messagerie utilisés dans l'exemple possèdent les descriptions suivantes (pour le format des signatures, voir annexe 2) :
Service de capture de température Service de messagerie
Méthodes getTemperature::r sendMessage:ss:b
Flux temperature::sr
Propriétés location:s
version:s
protocol:s
Le service de capture de température possède une méthode, getTemperature, n'ayant pas de
paramètres d'entrée et renvoyant un réel. Il propose également un flux, non paramétrable, composé
d'une chaîne de caractère (la localisation) et d'un réel (la température). Ses deux propriétés, location
et version, sont des chaînes de caractères. Le service de messagerie ne possède pas de flux, mais
propose la méthode sendMessage, dont les paramètres d'entrée sont le nom d'utilisateur et le
message à envoyer. Ce service n'a qu'une propriété, protocol, correspondant au protocole utilisé par
ce service.
Les flux proposés sont des flux de Tuples (voir annexe 3). Ces flux sont paramétrables, c'est-à-dire
que des paramètres peuvent être fournis lors de l'abonnement au flux, en accord avec sa signature.
Un tuple est une collection ordonnée d'objets, il correspond à une ligne dans une relation.
Par exemple, on pourrait imaginer développer un service de messagerie instantanée sur ce modèle.
Ce service proposerait un flux qui demande comme paramètres d'entrée un login et un mot de passe.
Le flux contiendrait alors les messages destinés à cet utilisateur. La signature d'un tel flux est
messages:ss:s.
3.4 Gestionnaires de ressources locaux
Le gestionnaire de ressources local recherche localement, dans son framework OSGi, les services
compatibles SoCQ ; et effectue la conversion dans le protocole réseau utilisé entre les gestionnaires
de ressources, UPnP.
La figure 3 présente le diagramme de classes du gestionnaire de ressources local.
La classe SoCQDiscoveryAgent permet de découvrir les nouveaux ISoCQServices se déclarant auprès
du framework OSGi. Cet agent notifie le LocalRM (Local Resource Manager) par les méthodes
registerSoCQService(ISoCQService service) et unregisterSoCQService(ISoCQService service).
9
Fig.3 : Diagramme de classes du gestionnaire de ressources local
Lorsqu'un nouveau service SoCQ est disponible, le LocalRM crée un nouvel objet SoCQUPnPDevice,
(voir annexe 4) représentant un périphérique au sens UPnP. L'API UPnP de Felix permet d'effectuer le
lien entre cet objet et le protocole réseau UPnP. Un périphérique au sens UPnP correspond à un
service au sens SoCQ. Un bundle proposant plusieurs services SoCQ sera donc converti en autant de
périphériques UPnP.
Un des avantages d'UPnP est qu'il est possible de développer des gestionnaires de ressources locaux
sous d'autres langages que java. Il suffit que ces gestionnaires de ressources respectent les
spécifications UPnP propres à la gestion de ressources pour SoCQ (voir annexe 4).
10
3.5 Gestionnaire de ressources global
Le gestionnaire de ressources global a pour rôle de découvrir les Services SoCQ UPnP mis à
disposition par les gestionnaires de ressources locaux. Il sert également à effectuer la conversion
inverse des gestionnaires de ressources locaux, c'est-à-dire convertir les périphériques UPnP en
proxys de services SoCQ.
La figure 4 présente le diagramme de classes du gestionnaire de ressources global.
Fig.4 : Diagramme de classes du gestionnaire de ressources global
11
Le gestionnaire de ressources global est composé de trois parties:
- La découverte de services UPnP compatibles SoCQ, effectuée par l'objet UPnPDiscoveryAgent
- La création d'un objet SoCQUPnPService implémentant l'interface ISoCQService. Cet objet
sert de proxy pour l'invocation des méthodes proposées par cette interface
- La gestion des ISoCQServices, effectuée par un GlobalRM (Global Resource Manager).
La classe UPnPDiscoveryAgent permet de découvrir les nouveaux SoCQUPnPDevices sur le réseau. A
chaque découverte, cet agent crée un SoCQUPnPService implémentant l'interface ISoCQService, qui
permet d'appeler les actions UPnP correspondant aux méthodes de l'interface ISoCQService. Une fois
ce service créé, l'agent notifie la GlobalRM par l'appel de la méthode
registerSoCQService(ISoCQService service) (respectivement unregisterSoCQService(ISoCQService
service) si le périphérique UPnP disparaît).
Le GlobalRM gère une liste de ces proxys de services SoCQ et les rend accessibles par les méthodes
définies par l'interface IGlobalRM.
3.6 Contrôleur du gestionnaire de ressources global
Le contrôleur fournit une interface graphique au gestionnaire de ressources global. Il permet de visualiser la liste des services présents dans l'environnement ainsi que leur description (fig.5). Il permet également d'invoquer leurs méthodes (fig.6), s'abonner / désabonner à leurs flux (fig.8) et récupérer la valeur de leurs propriétés (fig.9).
Dans les captures d'écrans des figures 5, 8 et 9, le service concerné est un service de capture de température virtuel. Pour la figure 6, il s'agit du service de messagerie instantanée.
Fig.5 : Interface du contrôleur du gestionnaire de ressources
La figure 5 présente l'interface du contrôleur du gestionnaire de ressources. Sur la gauche se trouve
la liste des identifiants de services du gestionnaire de ressources global. Lorsqu'un service est
sélectionné, sa description s'affiche au centre.
12
Fig.6 : Invocation de méthodes des services.
Sur la figure 6, on a d'abord invoqué la méthode getTemperature du service 1 (capture de
température), puis la méthode sendMessage du service 2 (service de messagerie). On observe dans
la partie inferieur du contrôleur les résultats de ces invocations.
Le résultat de l'invocation de la méthode sendMessage avec les paramètres visibles sur la figure 6 est
présenté figure 7. C'est un client de messagerie Jabber ouvert en tant que [email protected]
lyon.fr, qui a reçu le message "Hello world !" envoyé par le service de messagerie.
Fig.7 : Résultat de l'invocation de la méthode sendMessage.
Sur la figure 8, le contrôleur s'est abonné au flux de température des services 1 et 2, correspondant
respectivement à des capteurs de température virtuels dans le bureau et sur le toit. On voit dans les
traces les différents tuples reçus pour les deux flux.
Sur la figure 9, la propriété location du service 1 est sélectionnée. On peut ainsi visualiser sa valeur.
13
Fig.9 : Visualisation des propriétés.
Fig.8 : Abonnement à des flux de température.
3.7 Conclusion
L'aspect réseau était la difficulté de cette partie, d'une part parce qu'UPnP est particulièrement
contraignant en terme de développement, mais surtout parce que l'implémentation du service UPnP
proposé par Felix n'est pas très explicite pour la gestion des erreurs, et possède quelques bugs.
La partie gestion des ressources de ce projet représente un volume de 3140 lignes de code (57
classes Java) pour les gestionnaires de ressources et le contrôleur, et de 434 lignes (8 classes Java)
pour les exemples de services de capture de température et de messagerie.
14
4 Gestion des tables
4.1 Objectifs
Le gestionnaire de tables a pour but de fournir un catalogue de tables. Il doit s'occuper de l'accès
concurrent à ce catalogue, et des opérations sur les services.
Une table est un ensemble de tuples correspondant à un schéma. Dans SoCQ, les attributs d'une
table peuvent être réels, c'est-à-dire que la donnée associée est stockée, ou virtuels, dans ce cas, la
donnée ne possède qu'une existence logique au niveau du gestionnaire de tables et ne peut être
complétée que lors de l'exécution d'une requête. Les attributs virtuels sont utilisés lors de
l'invocation de binding patterns.
Un binding pattern est une règle associée à une table qui décrit la relation entre les attributs de cette
table et une méthode d'un service. Par exemple :
On considère la table Employee suivante, dont les attributs Message et Envoyé sont virtuels
et sont représentés par le caractère '*'. L'attribut Service contient l'identifiant du service à
utiliser lors de l'invocation du binding pattern. Ce service possède la méthode :
Boolean envoyerMessage(String message, String adresse).
Nom Adresse Service de messagerie Message (v) Envoyé (v)
Brice [email protected] 1 * *
Yann [email protected] 1 * *
Le binding pattern permet d'associer la méthode envoyerMessage à cette table. Il définit la
correspondance entre les attributs Message et Adresse de cette table et le paramètre
d'entrée message et adresse de la méthode envoyerMessage, et celle entre l'attribut Envoyé
et le paramètre de retour de cette méthode. L'attribut correspondant à l'identifiant du
service à utiliser est également défini par le binding pattern. Il s'agit ici de l'attribut Service de
messagerie.
Le gestionnaire de tables permet les opérations suivantes :
- création / suppression d'une table
- lecture d'une table
- ajout / suppression d'un tuple dans une table
- invocation d'un binding pattern associé à une table
4.2 Architecture
Le gestionnaire de tables, le gestionnaire de ressources global et le moteur SoCQ sont des modules
du même framework (OSGi).
15
Fig.10 : diagramme de déploiement du gestionnaire de tables
Le gestionnaire de ressources permet d'accéder à l'ensemble des services du système. Il s'occupe de
la découverte et de l'invocation à distance.
Le contrôleur de tables fournit une interface graphique pour visualiser et administrer le catalogue.
Le moteur SoCQ s'occupe de l'exécution des requêtes SoCQ.
4.3 Gestionnaire de tables
La figure 11 présente le diagramme de classes du gestionnaire de tables.
Le gestionnaire de tables possède un catalogue de tables. Pour résoudre les problèmes de
concurrence sur ce catalogue, l'accès à celui-ci est effectué uniquement par le thread principal du
gestionnaire de tables. Pour cela, on utilise un système de commandes asynchrones. Les différentes
commandes disponibles ainsi que leur fonctionnement sont détaillés dans la section 4.3.5.
Lors de l'appel d'une méthode du gestionnaire de tables, une commande, correspondant à l'action
demandée, est ajoutée dans une file interne. Dans son thread principal, le gestionnaire de tables
peut alors exécuter cette commande. A la fin de l'exécution, l'appelant est notifié. La figure 12
présente la séquence utilisée pour la création d'une table.
16
Fig.11 : diagramme de classes du gestionnaire de tables.
Fig.12 : diagramme de séquence de la création d'une table par l'intermédiaire d'une commande
17
Dans un souci d'optimisation de l'exécution, en particulier pour le moteur SoCQ, un autre mode
d'accès au catalogue est prévu : le thread principal du gestionnaire de tables passe la main à un
exécuteur de requêtes et lui donne un accès direct et exclusif au catalogue. Pour cela, le gestionnaire
de tables appelle la méthode execute() de l'exécuteur de requêtes en lui donnant la référence du
catalogue.
Les méthodes du catalogue et des tables sont synchrones. Elles possèdent leurs équivalents en
appels asynchrones par l'utilisation du système de commandes. S'il s'agit d'une méthode du
catalogue, la méthode asynchrone correspondante est fournie directement par le gestionnaire de
tables. S'il s'agit d'une méthode d'une table, un proxy TableProxy est utilisé (voir 4.3.3).
4.3.1 Catalogue
Le catalogue permet de :
- Récupérer la liste des tables.
- Récupérer un objet table.
- Créer une table en fournissant son schéma de relation et ses binding patterns si nécessaire.
- Supprimer une table.
4.3.2 Tables
Une table est représentée par un schéma. Ce schéma décrit les attributs de la table. Ces attributs
possèdent un nom, un type java (un objet Class) et une information booléenne indiquant s'il s'agit
d'un attribut virtuel.
Les tuples d'une table ne sont pas toujours stockés par le gestionnaire de table. S'il s'agit d'une table
représentant un flux, les tuples sont transmis aux lecteurs mais ne sont pas conservés.
Pour être compatible avec tous les types de tables (relation ou flux), la lecture utilise une file
d'événements (liste FIFO) comme intermédiaire (voir fig.13).
Fig.13 : lecture d'une table
Lecteur
Table
Evènements
donne la main aux exécuteurs de requêtes
exécute les commandes en attente
Gestionnaire de tables
18
S'il s'agit d'une table représentant une relation, la lecture entraîne une phase d'initialisation de la file
avec les tuples déjà présents dans la table. La file est ensuite actualisée en fonction des modifications
effectuées (ajout ou suppression de tuples) jusqu'au désabonnement de la lecture.
S'il s'agit d'une table représentant un flux, seuls les tuples du flux dont l'arrivée est postérieure à
l'abonnement seront ajoutés dans la file, car le gestionnaire de table ne stocke pas les flux. Et ce
jusqu'au désabonnement de la lecture. Pour une table de type flux, il ne peut y avoir que des ajouts.
Les opérations suivantes sont également disponibles sur une table :
- Lecture du contenu stocké d'une table (Abonnement avec une file d'évènements).
- Désabonnement de la lecture. La table arrête alors de mettre à jour la file correspondante.
- Ajout de tuples
- Suppression de tuples
- Invocation de binding patterns
4.3.3 TableProxy
Les méthodes des tables présentées précédemment ne sont utilisables que si on a accès direct et
exclusif au catalogue. Dans le cas contraire, lors de l'invocation asynchrone de la méthode getTable()
du gestionnaire de tables, celui-ci renvoie un objet TableProxy qui sert de proxy pour l'invocation des
méthodes d'une table. Lors de l'appel d'une méthode, le TableProxy ajoute la commande
correspondante dans la file de commandes du gestionnaire de tables.
4.3.4 Objets Future
Lors des invocations asynchrones, le retour de la méthode est un objet Future<V>. Cet objet, utilisant
les types génériques <V> [12] et inspiré de l'interface Future<V> [13] fourni par Java, permet de
notifier l'appelant lorsque la commande a été exécutée. Les méthodes utilisables par l'appelant sont :
public Boolean isDone();
public V get()throws Exception;
La méthode isDone() permet de vérifier si la commande a achevé son exécution, tandis que get()
permet d'attendre si nécessaire la fin de cette exécution. C'est également le seul moyen de récupérer
l'objet V, résultat de l'exécution de la commande.
Les méthodes utilisables par le gestionnaire de tables sont : public void executionComplete(V value);
public void setException(Exception e);
Elles permettent de notifier l'objet Future de la fin de l'exécution de la commande. Si l'exécution s'est
déroulée normalement, l'objet V est fourni, sinon une Exception, donnée par l'appel de la méthode
setException, est levée par la méthode get().
4.3.5 Commandes
Lors de l'exécution asynchrone d'une méthode, des commandes sont utilisées pour mettre en file
d'attente cette exécution. Les commandes possibles sont les suivantes :
19
Fig.14 : diagramme de classes du package commands
Ces commandes représentent les méthodes du catalogue ou des tables. Elles renvoient un objet
Future qui représente le résultat de cette exécution asynchrone.
Voici un exemple d'utilisation :
On considère la méthode suivante : Future<ITable> getTable(int key)
L'objet souhaitant récupérer la table utilise le code suivant :
Future<ITable> futureTable = tableManager.getFutureTable(1);
//Une commande est ajoutée dans la file de commandes du TableManager
ITable table = futureTable.get();
La méthode get() bloque jusqu'à ce que la table soit disponible. Lorsque le TableManager va exécuter
la commande, celle-ci va mettre à jour l'objet futuretable en appelant : futuretable.executionComplete(uneITable);
Il est également possible d'évite de bloquer sur la méthode get(). Pour cela, on peut utiliser le code
suivant :
Future<ITable> futureTable = tableManager.getFutureTable(1);
actions..
if( futureTable.isDone() ) {
20
//On sait que la table est disponible
ITable table = futureTable.get();
} else {
actions..
}
4.3.6 Binding Patterns
Un binding pattern permet de faire la correspondance entre des attributs d'une table et des
paramètres d'une méthode d'un service. Il permet également de savoir quel attribut correspond à un
identifiant de service, et de connaitre la méthode à invoquer.
L'appel de la méthode invoke() d'un binding pattern est asynchrone, cette méthode utilise donc
également un objet Future<Tuple[]> pour effectuer la notification.
On peut reprendre l'exemple du paragraphe 4.1 :
Nom Adresse Service Message (v) Envoyé (v)
Brice [email protected] 1 * *
Yann [email protected] 1 * *
Soit un binding pattern correspondant à la méthode Boolean envoyerMessage(String
adresse, String message).
Si on souhaite invoquer ce binding pattern sur le premier tuple de la table, l'appel de la méthode
invoke() sera le suivant :
/* On possède un Tuple tuple correspondant à la ligne 1.
* Ce tuple est complété en attribuant une valeur aux attributs virtuels
* correspondant aux paramètres d'entrée de la méthode.
* tuple = { "Brice", "[email protected]", 1 , "Ceci est un message" }
*/
Future<Tuple[]> futureTuples = bindingPattern.invoke(tuple);
/* cela va invoquer la méthode du service possédant l'identifiant 1
* envoyerMessage( "[email protected]", "Ceci est un message")
*/
Tuple[] result = futureTuples.get();
result contiendra un seul Tuple, qui lui-même contiendra un seul élément booléen correspondant au
résultat de l'invocation de la méthode envoyerMessage().
4.3.7 Gestionnaire de listes de services
Le gestionnaire de listes de services est un composant du gestionnaire de tables. Il permet au moteur
SoCQ ou au contrôleur de tables de créer des tables contenant des identifiants de services présents
dans l'environnement. Il se charge également de maintenir à jour ces tables. Chaque table est
associée à une SoCQServiceDescription (voir annexe 2) permettant de sélectionner les services en
fonction des méthodes, flux et propriétés qu'ils possèdent. La table contient un tuple pour chaque
service respectant ces critères.
Les seuls attributs réels contenus dans ces tables sont les propriétés de la SoCQServiceDescription
fournie. Les valeurs de ces attributs sont complétées avec la valeur de la propriété pour chaque
21
service. La table peut contenir d'autres attributs, mais ceux-ci doivent être virtuels car le gestionnaire
de listes de services ne peut pas attribuer arbitrairement une valeur à ceux-ci.
Une table créée par le gestionnaire de listes de services peut également posséder un ou plusieurs
binding patterns.
Par exemple, la table suivante contient des identifiants de service pour des capteurs de température,
possédant les propriétés Localisation et Version. Un binding pattern correspondant à la méthode
getTemperature() peut être associé à cette table, d'où la présence de l'attribut virtuel Température.
ID Service Localisation Version Température (v)
1 Bureau 0.1 *
3 Bureau 0.1 *
4 Couloir 0.1 *
4.4 Contrôleur de tables
Le contrôleur de tables fournit une interface graphique pour l'administration du catalogue du
gestionnaire de tables.
Il permet de visualiser la liste des tables (fig.15), de visualiser le contenu d'une table (fig.15 à 18) et
de créer une table (fig.19 et 20).
Fig.15 : Interface du contrôleur du gestionnaire de tables.
Sur la figure 15, on observe sur la gauche la liste des tables présentes dans le catalogue du
gestionnaire de tables. Leur nom et leur identifiant sont affichés. En sélectionnant une table, on peut
visualiser son contenu. Ici il s'agit de la table surveillance.
Fig.16 : Visualisation d'une table avec des attributs virtuels.
La table Employee montrée sur la figure 16 possède deux attributs virtuels : l'attribut Message et
l'attribut Sent. Cette table possède également un binding pattern, mais le contrôleur ne permet pas
de le visualiser.
22
Fig.17 : Table associée à un gestionnaire de listes de services.
La figure 7 montre la table TemperatureServices. Cette table est définie comme étant associée à la
description du capteur de température du tableau section 3.3. Pour rappel : on cherche donc un
service possédant la méthode getTemperature::r, le flux temperature::sr et les
propriétés Location:s et Version:s. Au moment de la capture d'écran pour la figure 17, aucun
service de capture de température n'est lancé.
Fig.18 : Table associée à un gestionnaire de listes de services, services lancés.
Deux services de captures de température sont lancés, et la table TemperatureServices est mise a
jour par le gestionnaire de listes de services, avec les identifiants des services et les valeurs des
propriétés présentes dans la description.
Le contrôleur du gestionnaire de tables permet également de créer une table. Cette création de table
fait appel à un parseur développé par ailleurs au sein du projet. Sur la figure 19, on va demander la
création d'une table avec l'instruction suivante :
CREATE RELATION marelation (unNom STRING, unChiffre INTEGER);
Fig.19 : Création de table.
On observe le résultat figure 20 : la table est créée.
Fig.20 : Résultat de la création de table.
Cependant, le contrôleur du gestionnaire de tables est encore à une phase préliminaire de
développement. Par exemple, il ne permet pas encore d'invoquer des binding patterns, ou de mettre
à jour des tuples dans une table.
23
4.5 Conclusion
L'accès concurrent aux tables était la difficulté de cette partie. L'architecture du gestionnaire de
tables a été en grande partie conçue autour de cet aspect. Une fois le fonctionnement du
gestionnaire de table défini, le développement n'a pas présenté de difficultés particulières.
La partie gestion des tables de ce projet représente un volume de 2163 lignes de code (36 classes
Java) pour le gestionnaire de tables et son contrôleur.
24
5 Expérimentations
Cette partie concerne l'exécution de la requête présentée dans le scénario de l'introduction :
SELECT Area, Manager, Threshold, Temperature, Sent
FROM Temperature T, Surveillance S, Employee E
WHERE S.Manager = E.Name
AND S.Area = T.Area
AND S.Threshold < T.Temperature
AND E.Message = S.AlertMessage
Un prototype du moteur SoCQ a été développé au sein du projet SoCQ pour pouvoir exécuter cette
requête.
Le système comporte :
- Le moteur SoCQ
- Le gestionnaire de tables
- Le contrôleur du gestionnaire de tables
- Le gestionnaire de ressources global
- Un gestionnaire de ressources local
- Deux services de capture de température virtuels
- Un service de messagerie
- Les bundles OSGi nécessaires au fonctionnement du système :
o La librairie smack [14] pour le service de messagerie
o Le service UPnP de Felix
Le serveur de messagerie Jabber [15] est installé sur une autre machine du réseau local.
Tous ces éléments sont présents sous forme de bundle OSGi. Pour cette expérimentation, ceux-ci
sont installés sur le même framework.
Les tables suivantes sont créées lors d'une phase d'initialisation :
- MessageServices
Cette table utilise un gestionnaire de listes de services pour récupérer l'identifiant de service
correspondant à un service de messagerie.
- TemperatureServices
De même, cette table utilise un gestionnaire de liste de services pour récupérer les identifiants de
services correspondant aux services de capture de température.
25
- Employee
Cette table est créée statiquement, puis complétée par une requête SoCQ annexe qui récupère
dynamiquement l'identifiant de service contenu dans la table MessageServices. Un binding pattern
correspondant à la méthode envoyerMessage est associé à cette table.
- Surveillance
Cette table est créée et complétée de manière statique.
- Temperature
Cette table est crée de manière statique. Elle est initialement vide mais par un opérateur SoCQ
spécifique, on y associe les flux de température des services inscrits dans la table
TemperatureServices. Après quelques secondes d'exécution, la table possède les tuples suivants :
Les capteurs de température sont des capteurs virtuels. On peut choisir la température courante
grâce à un curseur. L'interface est présentée figure 21.
Fig.21 : Interface d'un capteur de température virtuel.
26
Lorsqu'on augmente la température du capteur virtuel associé à la localisation Toit, on obtient la
table suivante :
La température dépassant le seuil défini dans la table Surveillance (27°C), la requête commande
l'execution du binding pattern de la table Employee avec le message correspondant de la table
surveillance. La figure 22 présente le résultat de cette exécution.
Fig.22 : Résultat de l'invocation du binding pattern.
Le résultat de la requête est enregistré dans une table Results. Après avoir également augmenté la
température virtuelle du bureau on obtient le résultat présenté figure 23 :
27
Fig.23 : résultat de la requête.
Cette expérimentation permet de vérifier le bon fonctionnement du système dans son ensemble car
elle fait appel à quasiment toutes les fonctionnalités du gestionnaire de tables ainsi que des
gestionnaires de ressources.
28
6 Conclusion
La requête présentée dans la partie expérimentation permet de voir l'impact de SoCQ sur le
développement d'applications appliquées aux systèmes pervasifs : une application de surveillance de
température tient en une requête de six lignes ! De plus, les services sont réutilisables et partagés
pour toutes les applications du système, ce qui est une caractéristique notable pour ce type
d'environnement.
De par sa modularité, le système permet de nombreuses extensions, comme le développement de
nouveaux services, facilité par la prise en charge des aspects réseaux par les gestionnaires de
ressources; ou encore l'amélioration de certains éléments du système, comme par exemple le
contrôleur de tables, dont les fonctionnalités sont pour l'instant assez limitées. De même, il est
possible de changer le protocole réseau utilisé par les gestionnaires de ressources sans avoir à
modifier le reste du système.
Ce projet de fin d'étude est particulièrement intéressant de par les nombreux domaines qui lui sont
associés : systèmes pervasifs, réseau et gestion des tables avec un petit coté "base de données".
La communication entres les différents gestionnaires de ressources, ainsi que les problèmes d'accès
concurrent au gestionnaire de tables ont induit une phase de conception importante. Il est
intéressant d'avoir pu contribuer à l'élaboration des solutions à ces problèmes.
29
7 References
[1] M. Weiser. The Computer for the 21st Century. Scientific American, 265(3):94–104, 1991.
[2] Y. Gripay, F. Laforest, J-M Petit. Towards Action-Oriented Continuous Queries in Pervasive
Systems. Bases de données Avancées 2007 (BDA'07), Marseille, pp. 1-20, 2007.
[3] Y.Gripay. Service-oriented Continuous Queries for Pervasive Systems. EDBT 2008 PhD
Workshop, 2008.
[4] SoCQ Project. http://socq.liris.cnrs.fr/.
[5] UPnP Forum. Universal Plug and Play. http://www.upnp.org/.
[6] OSGi Alliance. OSGi. http://www.osgi.org/.
[7] Sun Microsystems. Remote Method Invocation (RMI).
http://java.sun.com/javase/technologies/core/basic/rmi/.
[8] Object Management Group. Common Object Request Broker Architecture (CORBA).
http://www.omg.org/technology/documents/formal/corba_iiop.htm.
[9] Apache Felix. http://felix.apache.org/.
[10] Maven. http://maven.apache.org/.
[11] Eclipse Foundation. Eclipse. http://www.eclipse.org/.
[12] Sun Microsystems. Generics.
http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html
[13] Sun Microsystems. Inteface Future<V> API.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html
[14] Ignite Realtime. Smack API. http://www.igniterealtime.org/projects/smack/.
[15] XMPP Standards Foundation. Jabber. http://www.jabber.org/.
[16] UPnP Forum. UPnP Device Architecture 1.0.
http://www.upnp.org/specs/arch/UPnP-DeviceArchitecture-v1.0.pdf
30
8 Annexes
8.1 Interface ISoCQService
Un service au sens SoCQ est une entité possédant des méthodes, des flux et des propriétés. Tout service doit implémenter l'interface ISoCQService et ainsi permettre de récupérer sa description (voir annexe 2), de s'abonner/désabonner à ses flux et d'invoquer ses méthodes.
public interface ISoCQService
public SoCQServiceDescription getDescription()
public String[] getProperties(String[] propertyNames) throws
PropertyNotFoundException
public Tuple[] invoke(String methodName, Tuple[] arguments) throws
MethodNotFoundException, ArgumentException
public void subscribeStream(IStreamListener listener, String
streamName, Tuple[] arguments) throws StreamNotFoundException,
ArgumentException;
public void unsubscribeStream(IStreamListener listener) throws
StreamNotFoundException;
31
8.2 Classe SoCQServiceDescription
La classe SoCQServiceDescription contient la description d'un service. Il possède des signatures de
méthodes et de flux, ainsi que des noms de propriétés.
Cette classe possède également des méthodes utilitaires, comme la méthode includes, qui
permet de vérifier qu'une description contient toutes les méthodes, flux et propriétés d'une autre.
public class SoCQServiceDescription
public SoCQServiceDescription(String[] methods, String[] streams,
String[] properties)
public String[] getMethodsList()
public String[] getStreamsList ()
public String[] getPropertiesList()
public int hashCode()
public boolean equals(Object o)
public String toString()
public boolean includes(SoCQServiceDescription description)
Les signatures de ces méthodes et flux, ainsi que les noms des propriétés sont contenues dans une description.
Les signatures des méthodes et flux sont formatées de la manière suivante :
NomDeMethode:ParamètresEntrée:ParamètresSortie
Les paramètres d'entrée et de sortie sont représentés par une succession de caractères parmi 's', 'i',
'r', 'c', 'b', 'B', qui correspondent chacun à un type d'objet :
Caractère Type
s String
i Integer
r Double
c Character
b Boolean
B Binaire (codé en Base 64)
Par exemple, la méthode Boolean sendMessage(String nom, String message)
possède la signature sendMessage:ss:b.
Les propriétés sont représentées de la manière suivante :
NomDePropriete:Format
Le format est également un caractère représentant le type d'objet associé à la propriété. Par
exemple, la propriété Location : 'Bureau' possède la signature Location:s.
32
8.3 Classe Tuples
La classe Tuple représente une collection ordonnée d'objets. Les paramètres d'entrée et de sortie des
méthodes et des flux d'un service SoCQ sont des tableaux de Tuples.
Les types des objets stockés sont définis par les signatures des méthodes et flux. Ces objets sont
stockés dans des Fields, qui enregistrent l'objet et son type (sa classe java).
Les classes utilisées dans la définition des tuples sont les suivantes :
public class Tuple public Tuple() public Tuple(Object object) public Tuple(Object[] objects) public void addField(Object object) public String toString() public int getLength() public Field[] getFields() public Field getField(int i) public TupleFormat getFormat()
public class Field public Field(Object o) public String toString() public Class<?> getType() public Object getValue() public void setValue(Object object)
public class TupleFormat public static TupleFormat getInputFormat(String methodSignature) public static TupleFormat getOutputFormat(String methodSignature) public TupleFormat(String format public TupleFormat(Class<?>[] types) public String toString() public int getLength() public Class<?> getType(int i)
33
8.4 Spécifications UPnP pour la gestion des ressources
Un service au sens SoCQ est converti en périphérique UPnP par le gestionnaire de ressources local.
Ce périphérique doit posséder les propriétés suivantes :
FRIENDLY_NAME : "SoCQService"
UDN : "uuid:SoCQService" suivi d'un entier compris entre 0 et
Integer.MAX_VALUE (java). exemple : "uuid:SoCQService34"
MODEL_NAME : "SoCQService"
TYPE : "urn:schemas-upnp-org:device:SoCQService:1"
ID : "uuid:SoCQService"" suivi d'un entier compris entre 0 et
Integer.MAX_VALUE (java). exemple : "uuid:SoCQService34"
Ce périphérique possède un seul service (au sens UPnP) avec l'identifiant "urn:upnp-
org:serviceId:SoCQService:1" et les actions [16] suivantes :
Action Identifiant Paramètres d'entrée
Paramètres de sortie
GetMethodsListAction "getMethodsList" aucun "methodsList"
GetPropertiesListAction "getPropertiesList" aucun "propertiesList"
GetStreamsListAction "getStreamsList" aucun "streamsList"
GetPropertiesAction "getProperties" "keys" "properties"
InvokeAction "invoke" "methodName" "inputTuples"
"outputTuples"
SubscribeStreamAction "subscribeStream" "streamName" "inputTuples" "serviceId"
"streamId"
UnsubscribeStreamAction "unsubscribeStream" "streamId" "unsubscribed"
Ces actions sont détaillées plus loin.
Il possède aussi une variable d'état UPnP x_SoCQStream utilisée pour transmettre les flux.
8.4.1 Conversions
Les arguments d'entrée et de sortie des actions UPnP sont des String. Les gestionnaires de ressources
se chargent d'effectuer les conversions selon les normes suivantes :
8.4.1.1 String[]
Les éléments de ce tableau sont séparés par le caractère "|".
exemple :
{ "valeur1", "valeur2" } donne "valeur1|valeur2"
8.4.1.2 Tuple[]
Les tuples sont, de la même manière que les tableaux de strings, séparés par le caractère "|" ; que ce
soit entre les champs de ce tuple ou entre les tuples.
La conversion de la chaîne de caractères vers le tuple nécessite la connaissance du format du tuple.
Ce format est donné dans les signatures des méthodes et des flux.
34
exemple :
{ ("VirtualDevice1",'A')
("VirtualDevice2",'C')
("VirtualDevice3",'B') }
donne "VirtualDevice1|A|VirtualDevice2|C|VirtualDevice3|B"
8.4.1.3 Boolean
Les booléens sont convertis en chaines caractères, avec true = "t" et false = "f".
8.4.2 getMethodsList, getPropertiesList et getStreamsList
La méthode UPnP getMethodsList renvoie la liste des méthodes de la description du service. Cette
liste est convertie en chaine de caractères en séparant les méthodes par le caractère '|'.
exemple :
pour un service possédant les méthodes getTemperature::r et sendMessage:ss:b, getMethods
renvoie "getTemperature::r|sendMessage:ss:b".
Les méthodes getPropertiesList et getStreamsList utilisent le même format en séparant les valeurs
par des '|'.
8.4.3 getProperties
La méthode getProperties(String propertyNames) utilise également la séparation par des '|' pour les
clés et les valeurs des propriétés.
exemple : getProperties("Location|DeviceName")
retourne "A|VirtualDevice 1"
8.4.4 invoke
L'action InvokeAction(String methodName, String inputTuples) correspond à la méthode
invoke(String methodName, Tuple[] arguments) de l'interface ISoCQService. Les tuples sont convertis
en String en séparant les champs et les tuples par le caractère '|'.
exemple :
InvokeAction.invoke("sendMessage", "Brice|Bonjour|Yann|Bonjour") correspond a
l'appel : ISoCQService.invoke("sendMessage", new Tuple[] {
new Tuple( { "Brice", "Bonjour" } ),
new Tuple( { "Yann", "Bonjour" } )
} );
8.4.5 subscribeStream
Pour chaque abonnement au flux d'un service, le gestionnaire de ressources local est chargé de
générer un identifiant de flux.
35
La chaine de caractère retourné par la méthode String subscribeStream(String serviceId, String
streamName, String inputTuples) est donc la représentation en base 10 d'un entier compris entre 0
et Integer.MAX_VALUE (java).
Le String serviceId est généré par le gestionnaire de ressources global. Il s'agit également de la
représentation en base 10 d'un entier compris entre 0 et Integer.MAX_VALUE (java). Cet
identifiant est utilisé pour identifier le service lors de la notification de flux (voir plus loin : Flux).
De même que pour l'action invoke, subscribeStream utilise la converstion Tuple[]-String.
8.4.6 unsubscribeStream
La méthode unsubscribeStream(String streamId) retourne un String contenant "t" (pour true) si le
désabonnement à été effectué, et "f" (pour false) sinon. Le String streamId est l'identifiant retourné
par la méthode subscribeStream.
8.4.7 Flux
Les flux sont également convertis en chaine de caractères suivant le format :
Id:StreamName:ServiceId:StreamId:Tuples.
Id est la représentation en base 10 d'un entier dont la valeur arbitraire doit changer entre deux
valeurs de flux successifs. En effet, une variable d'état UPnP n'est pas transmise si elle contient deux
fois de suite là même valeur.
StreamName est le nom du flux, serviceId est l'identifiant fourni par le gestionnaire de ressources
global lors du subscribeStream, streamId est l'identifiant généré par le gestionnaire de ressources
local.
La variable d'état UPnP x_SoCQStream contient la valeur du flux, ce qui permet au gestionnaire de
ressources global de la récupérer en s'abonnant à cette variable d'état.
exemple :
Soit un service possédant l'identifiant 5 et un flux temperature avec l'identifiant 23 contenant les
tuples (temperature,localisation), on obtient :
12:temperature:5:23:25.5|A
L'Id (ici 12) doit être différente de celui utilisé pour les valeurs précédente et suivante du flux.