Espaces de noms gérés

Résumé

Introduction

Les espaces de noms gérés sont utilisés dans le SDK Weave pour fournir aux développeurs et aux intégrateurs du SDK Weave des conseils et des sous-titres sur la désignation d'ensembles d'API spécifiques dans le SDK. Ils peuvent ainsi planifier et prédire leur chemin de migration entre les versions du SDK Weave et, potentiellement, gérer plusieurs API Weave simultanées pour un module donné.

Désignation

Les espaces de noms gérés peuvent être gérés selon l'une des quatre désignations suivantes:

Développement

Tout espace de noms géré avec la désignation "Développement" indique aux développeurs et aux intégrateurs que les API qu'ils contiennent sont en cours de développement, peuvent être modifiées et ne sont pas officiellement compatibles. Les intégrateurs sont généralement déconseillés d'utiliser ces API, sauf s'ils y sont spécifiquement invités.

Suivant

Tout espace de noms géré avec la désignation Next indique aux développeurs et aux intégrateurs que les API qu'ils contiennent, bien qu'elles aient été largement développées, peuvent encore être modifiées et sont prises en charge à des fins d'évaluation préliminaire. Les API ainsi désignées représentent le prochain front évolutif d'une API du SDK Weave et deviendront les API actuelles par défaut lors d'un cycle de versions majeures dans un avenir immédiat ou dans un avenir proche.

La rétrocompatibilité, tant du point de vue des API que du protocole Over The Wire, peut exister, mais n'est pas garantie dans les API ainsi désignées.

La désignation de l'espace de noms géré Next permet aux développeurs et aux intégrateurs de savoir où se dirige le SDK Weave en leur indiquant ce qui deviendra l'API par défaut actuelle dans une prochaine version.

La désignation de l'espace de noms géré Next est facultative, de sorte qu'un espace de noms géré peut passer à un cycle de vie sans l'utiliser (voir Cycle de vie d'un espace de noms géré).

Actuelle

Tout espace de noms géré avec la désignation "Current" ou tout espace de noms non géré (c'est-à-dire, dépourvu d'espace de noms géré) représente l'API actuelle par défaut et officielle compatible avec cette partie ou ce module du SDK Weave. Même s'il peut encore y avoir des améliorations continues pour ces API, les modifications seront en grande partie incrémentielles et la rétrocompatibilité doit être maintenue, tant via les API que via le réseau filaire.

La désignation de l'espace de noms géré actuel est facultative, de sorte qu'un espace de noms géré peut passer par un cycle de vie sans l'utiliser (voir Cycle de vie d'un espace de noms géré). En fait, tout espace de noms non géré est implicitement actuel.

Ancien

Tout espace de noms géré avec l'ancienne désignation indique aux développeurs et aux intégrateurs que les API qu'elles contiennent sont obsolètes et ont été remplacées par une nouvelle API actuelle. Ces API représentent ce qui était anciennement l'API actuelle.

Les API ainsi désignées disparaîtront complètement lors de la prochaine version majeure du SDK Weave. Par conséquent, les développeurs et les intégrateurs doivent établir des plans de migration afin de ne plus utiliser ces API s'ils ont l'intention de rester à la pointe des versions du SDK Weave.

Cycle de vie d'un espace de noms géré

La figure suivante illustre le cycle de vie d'un espace de noms géré lors du passage de l'espace de noms "Développement" à l'ancien, voire de l'ancien:

.-------------.      .- - - .      .- - - - -.      .--------.
| Development | -.->   Next   -.->   Current   ---> | Legacy |
'-------------'  |   '- - - '  |   ' - - - - '      '--------'
                 |             |
                 '-------------'

Si vous l'utilisez, le cycle de vie de l'espace de noms géré commence par la désignation "Développement".

Une fois le développement terminé et le code prêt pour l'évaluation et l'intégration, la désignation migre vers "Next" (Suivant) ou "Current" (Actuelle). Il est également possible que la désignation soit abandonnée et que l'espace de noms géré ne soit plus utilisé, ce qui la rend implicitement actuelle.

Si le code doit être intégré au code actuel et qu'il ne le supplante pas encore, la désignation doit migrer vers Next. Si le code doit supplanter le code actuel, la désignation doit migrer vers Current.

Avec la désignation "Next", une fois que le code a passé le nombre souhaité de cycles de publication et d'évaluation, la désignation migre vers "Current" (courant). Là encore, la désignation peut être complètement abandonnée.

En utilisant la désignation "Current", si le code doit être supplanté par un nouveau code, mais doit encore être géré pendant un certain nombre de cycles de publication, la désignation migre vers l'ancien.

Dans la désignation "Ancienne", le code est à terme supprimé du SDK Weave.

Utiliser des espaces de noms gérés

Les utilisateurs du SDK Weave peuvent interagir avec les espaces de noms gérés soit en tant que développeur, en étendant et en maintenant le code existant, ou en tant qu'intégrateur, en intégrant Weave dans leur propre code d'application, de plate-forme et de système. Les deux sections suivantes détaillent les recommandations concernant les espaces de noms gérés par Weave selon ces deux perspectives.

Utiliser des espaces de noms gérés en tant que développeur

L'une des missions clés du développeur du SDK Weave est d'améliorer et de développer de nouvelles API et fonctionnalités du SDK Weave tout en prenant en charge, dans de nombreux cas, les déploiements d'API et de fonctionnalités existants.

Lorsqu'il n'est pas possible de satisfaire ces deux domaines d'action de manière rétrocompatible au sein de la même API, les espaces de noms gérés fournissent un mécanisme permettant de gérer ces API en parallèle, sans perturber les déploiements d'API et de fonctionnalités existants.

Prenons l'exemple d'un profil Weave, Mercury, qui existe actuellement dans la hiérarchie d'espaces de noms non gérée suivante:

namespace nl {
namespace Weave {
namespace Profiles {
namespace Mercury {

// ...

}; // namespace Mercury
}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

et les en-têtes publics suivants:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp

où Mercury.hpp est l'en-tête du module "parapluie". La plupart des intégrateurs n'incluent que l'en-tête "parapluie" du module, comme illustré ci-dessous:

#include 

Cependant, le développeur de Mercury a atteint un stade où il est nécessaire de développer une nouvelle génération d'API et, éventuellement, de protocole de communication sans fil qui ne sont pas rétrocompatibles avec les déploiements existants. L'utilisation d'espaces de noms gérés peut permettre d'atteindre cet objectif sans interrompre les déploiements existants.

Déplacer l'espace de noms existant vers l'espace de noms actuel

Afin de continuer à assurer la compatibilité avec la version actuelle de l'API et des fonctionnalités pour les intégrations déployées existantes, la première tâche consiste à déplacer le code actuel:

% cd src/lib/profiles/mercury
% mkdir Current
% mv Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp *.cpp Current/

Notez qu'en plus de déplacer les fichiers, les protections incluses dans l'en-tête pour les fichiers déplacés doivent également être renommées, ce qui peut les décorer avec "_CURRENT", car de nouveaux fichiers portant le même nom seront créés à leur place ci-dessous.

Une fois le code déplacé, l'étape suivante consiste à gérer l'espace de noms avec la désignation appropriée (ici, "Current"). Commencez par créer un en-tête qui définit l'espace de noms géré, sous la forme "Current/MercuryManagednamespace.hpp". Il est préférable de créer un tel en-tête plutôt que de répéter et de dupliquer ce contenu dans chaque fichier d'en-tête lorsqu'il existe plusieurs fichiers d'en-tête.

% cat << EOF > Current/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current
#error Compiling Weave Mercury current-designation managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Current
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
EOF

Ensuite, insérez cet en-tête avant les autres instructions d'inclusion spécifiques au module dans les en-têtes existants. Exemple :

#include 

#include 

Créer des en-têtes de compatibilité

Toutefois, il ne suffit pas de déplacer les en-têtes existants vers un nouvel emplacement et de gérer uniquement leur espace de noms pour garantir le bon fonctionnement des déploiements existants. En effet, ils utilisent tous des instructions d'inclusion qui spécifient les en-têtes qui viennent d'être déplacés ci-dessus.

Pour résoudre ce problème, vous devez créer des en-têtes de wrapper de compatibilité dont les noms correspondent à ceux qui viennent d'être déplacés.

% touch Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp

Si seul un espace de noms géré désigné par Current est créé sans créer d'espace de noms géré "Development" ou "Next" pour l'accompagner, le contenu de ces fichiers peut simplement se composer d'une protection d'inclusion d'en-tête et d'une directive d'inclusion spécifiant l'en-tête nouvellement déplacé du même nom:

#ifndef _WEAVE_MERCURY_BAR_HPP
#define _WEAVE_MERCURY_BAR_HPP

#include 

#endif // _WEAVE_MERCURY_BAR_HPP

Toutefois, si un espace de noms géré "Development" ou "Next" est également créé pour prendre en charge de nouveaux développements incompatibles, des opérations légèrement plus complexes doivent être effectuées.

Comme précédemment, un en-tête pour la configuration de l'espace de noms géré est créé (ici, MercuryManagednamespace.hpp). Là encore, il est préférable de répéter et de dupliquer ce contenu dans chaque fichier d'en-tête lorsqu'il y a plusieurs fichiers d'en-tête.

% cat << EOF > MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE)                             \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current) \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development)
#error "WEAVE_CONFIG_MERCURY_NAMESPACE defined, but not as namespace kWeaveManagedNamespace_Current or kWeaveManagedNamespace_Development"
#endif

#if !defined(WEAVE_CONFIG_MERCURY_NAMESPACE)
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
EOF

Notez que, comme vous le souhaitez, la désignation de l'espace de noms géré est "Current" (actuel) par défaut si aucune configuration n'a été définie.

Une fois cet en-tête en place, les en-têtes du wrapper de compatibilité peuvent être modifiés pour contenir les éléments suivants:

#include 

#if WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development
#include 
#else
#include 
#endif // WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development

ou tout ce qui est approprié pour le cas d'utilisation de la gestion des espaces de noms concerné.

Créer des contenus en développement

À ce stade, l'infrastructure est en place et permet de commencer à créer de nouvelles fonctionnalités et API en plus des API existantes.

% mkdir Development
% touch Development/Mercury.hpp Development/Bar.hpp Development/Foo.hpp Development/Foobar.hpp
% cat << EOF > Development/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development
#error Compiling Weave Mercury development-designated managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Development
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Development
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
EOF

Bien entendu, si un module est beaucoup plus simple que l'exemple présenté ici et qu'il ne comporte pas beaucoup de classes, de sources, de fichiers ou d'en-têtes, tout cela peut être fait dans le même fichier d'en-tête, sans avoir à déplacer les fichiers ni à créer plusieurs en-têtes de configuration et de compatibilité autonomes. Toutefois, avec cet exemple complexe, elle devrait inspirer des solutions d'espaces de noms gérés, du plus complexe au simple.

Utiliser des espaces de noms gérés en tant qu'intégrateur

L'un des principaux objectifs de l'intégrateur du SDK Weave est d'inclure les en-têtes d'API publics appropriés pour le SDK Weave, ainsi que d'intégrer et de développer des applications associées.

Prenons l'exemple d'un profil Weave, Mercury, qui comporte les espaces de noms gérés Next, Current et Legacy, dont les en-têtes publics sont structurés comme suit:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp
  • Weave/Profiles/Mercury/Next/Mercury.hpp
  • Weave/Profiles/Mercury/Next/Bar.hpp
  • Weave/Profiles/Mercury/Next/Foo.hpp
  • Weave/Profiles/Mercury/Next/Foobar.hpp
  • Weave/Profiles/Mercury/Current/Mercury.hpp
  • Weave/Profiles/Mercury/Current/Bar.hpp
  • Weave/Profiles/Mercury/Current/Foo.hpp
  • Weave/Profiles/Mercury/Current/Foobar.hpp
  • Weave/Profiles/Mercury/Legacy/Mercury.hpp
  • Weave/Profiles/Mercury/Legacy/Bar.hpp
  • Weave/Profiles/Mercury/Legacy/Foo.hpp
  • Weave/Profiles/Mercury/Legacy/Foobar.hpp

où Mercury.hpp est l'en-tête du module "parapluie".

Sauf si le cas d'utilisation en question justifie d'inclure explicitement un module géré par espace de noms dans Weave, par exemple:

#include 

il est préférable de référencer les en-têtes publics du module Weave en fonction de leur chemin d'accès par défaut non géré (par exemple, Weave/Profiles/Mercury/Mercury.hpp). Cela permet de suivre la progression du développement des API sans modifier continuellement les directives include d'un projet, car celles-ci circulent tout au long du lifecycle géré.

Grâce à cette stratégie, les déploiements peuvent ensuite recibler leur code avec une autre désignation d'espace de noms géré (par exemple, la désignation Current) en spécifiant la configuration souhaitée dans le préprocesseur C/C++. Vous pouvez effectuer cette opération dans la ligne de commande, dans le code source, ou dans un en-tête de configuration ou de préfixe:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current

et utilisez le chemin d'inclusion non géré / non qualifié:

#include 

Lorsque et si la désignation de l'espace de noms géré change pour les API ciblées (par exemple, de "Current" à "Legacy", il vous suffit d'ajuster la définition du préprocesseur) :

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Legacy