blob: 74dbde7783c71e23e85cfe3a23df833a720acd4b [file] [log] [blame]
Alexander Afanasyeva9034b02014-01-26 18:32:02 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi2d491752017-07-14 21:32:05 +00002/*
Davide Pesavento15b55052018-01-27 19:09:28 -05003 * Copyright (c) 2014-2018, Regents of the University of California,
Davide Pesavento1d7e7af2015-10-10 23:54:08 +02004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Steve DiBenedettoef04f272014-06-04 14:28:31 -060024 */
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
27#define NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080028
Davide Pesavento47ab0292015-11-02 18:45:39 +010029#include "channel.hpp"
Junxiao Shi38b24c72017-01-05 02:59:31 +000030#include "face-system.hpp"
Davide Pesaventoe5eebad2017-04-06 20:23:26 -040031
Junxiao Shi38b24c72017-01-05 02:59:31 +000032#include <boost/range/adaptor/map.hpp>
33#include <boost/range/algorithm/copy.hpp>
Junxiao Shi2d491752017-07-14 21:32:05 +000034#include <ndn-cxx/encoding/nfd-constants.hpp>
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080035
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080036namespace nfd {
Junxiao Shi38b24c72017-01-05 02:59:31 +000037namespace face {
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080038
Junxiao Shi0ba6d642017-07-17 00:53:22 +000039/** \brief Parameters to ProtocolFactory constructor
40 *
41 * Every ProtocolFactory subclass is expected to have a constructor that accepts CtorParams,
42 * which in turn passes it to ProtocolFactory base class constructor. Parameters are passed as a
43 * struct rather than individually, so that a future change in list of parameters does not
44 * require updates to subclass constructors.
45 */
46struct ProtocolFactoryCtorParams
47{
48 FaceCreatedCallback addFace;
49 shared_ptr<ndn::net::NetworkMonitor> netmon;
50};
51
Junxiao Shi2d491752017-07-14 21:32:05 +000052/** \brief Provides support for an underlying protocol
Junxiao Shi38b24c72017-01-05 02:59:31 +000053 * \sa FaceSystem
54 *
55 * A protocol factory provides support for an underlying protocol and owns Channel objects.
56 * It can process a subsection of face_system config section and create channels and multicast
57 * faces accordingly.
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020058 */
Junxiao Shi38b24c72017-01-05 02:59:31 +000059class ProtocolFactory : noncopyable
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080060{
Junxiao Shib47247d2017-01-24 15:09:16 +000061public: // registry
Junxiao Shi0ba6d642017-07-17 00:53:22 +000062 using CtorParams = ProtocolFactoryCtorParams;
63
Junxiao Shi2d491752017-07-14 21:32:05 +000064 /** \brief Register a protocol factory type
Junxiao Shib47247d2017-01-24 15:09:16 +000065 * \tparam S subclass of ProtocolFactory
66 * \param id factory identifier
67 */
68 template<typename PF>
69 static void
70 registerType(const std::string& id = PF::getId())
71 {
72 Registry& registry = getRegistry();
73 BOOST_ASSERT(registry.count(id) == 0);
Junxiao Shi0ba6d642017-07-17 00:53:22 +000074 registry[id] = &make_unique<PF, const CtorParams&>;
Junxiao Shib47247d2017-01-24 15:09:16 +000075 }
76
Junxiao Shi2d491752017-07-14 21:32:05 +000077 /** \brief Create a protocol factory instance
Junxiao Shib47247d2017-01-24 15:09:16 +000078 * \retval nullptr if factory with \p id is not registered
79 */
80 static unique_ptr<ProtocolFactory>
Junxiao Shi0ba6d642017-07-17 00:53:22 +000081 create(const std::string& id, const CtorParams& params);
Junxiao Shib47247d2017-01-24 15:09:16 +000082
Junxiao Shi2d491752017-07-14 21:32:05 +000083 /** \brief Get registered protocol factory ids
Junxiao Shib47247d2017-01-24 15:09:16 +000084 */
85 static std::set<std::string>
86 listRegistered();
87
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080088public:
Junxiao Shi0ba6d642017-07-17 00:53:22 +000089 /** \brief Base class for all exceptions thrown by ProtocolFactory subclasses
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080090 */
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020091 class Error : public std::runtime_error
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080092 {
Davide Pesavento1d7e7af2015-10-10 23:54:08 +020093 public:
94 explicit
95 Error(const std::string& what)
96 : std::runtime_error(what)
97 {
98 }
Alexander Afanasyeva9034b02014-01-26 18:32:02 -080099 };
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800100
Junxiao Shib47247d2017-01-24 15:09:16 +0000101 virtual
102 ~ProtocolFactory() = default;
103
104#ifdef DOXYGEN
Junxiao Shi2d491752017-07-14 21:32:05 +0000105 /** \brief Get id for this ProtocolFactory
Junxiao Shib47247d2017-01-24 15:09:16 +0000106 *
107 * face_system.factory-id config section is processed by the protocol factory.
108 */
109 static const std::string&
110 getId();
111#endif
112
Junxiao Shi2d491752017-07-14 21:32:05 +0000113 /** \brief Process face_system subsection that corresponds to this ProtocolFactory type
Junxiao Shi38b24c72017-01-05 02:59:31 +0000114 * \param configSection the configuration section or boost::null to indicate it is omitted
115 * \param context provides access to data structures and contextual information
116 * \throw ConfigFile::Error invalid configuration
117 *
118 * This function updates \p providedSchemes
119 */
120 virtual void
121 processConfig(OptionalConfigSection configSection,
Junxiao Shic3443042017-01-26 17:21:35 +0000122 FaceSystem::ConfigContext& context) = 0;
Junxiao Shi38b24c72017-01-05 02:59:31 +0000123
Junxiao Shi2d491752017-07-14 21:32:05 +0000124 /** \brief Get FaceUri schemes accepted by this ProtocolFactory
Junxiao Shi38b24c72017-01-05 02:59:31 +0000125 */
126 const std::set<std::string>&
127 getProvidedSchemes()
128 {
129 return providedSchemes;
130 }
131
Davide Pesavento15b55052018-01-27 19:09:28 -0500132 /** \brief Encapsulates a face creation request and all its parameters
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800133 *
Eric Newberry944f38b2017-07-20 20:54:22 -0400134 * Parameters are passed as a struct rather than individually, so that a future change in the list
135 * of parameters does not require an update to the method signature in all subclasses.
136 */
Davide Pesavento15b55052018-01-27 19:09:28 -0500137 struct CreateFaceRequest
Eric Newberry944f38b2017-07-20 20:54:22 -0400138 {
139 FaceUri remoteUri;
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400140 optional<FaceUri> localUri;
Davide Pesavento15b55052018-01-27 19:09:28 -0500141 FaceParams params;
Eric Newberry944f38b2017-07-20 20:54:22 -0400142 };
143
Davide Pesavento15b55052018-01-27 19:09:28 -0500144 /** \brief Try to create a unicast face using the supplied parameters
Eric Newberry944f38b2017-07-20 20:54:22 -0400145 *
Davide Pesavento15b55052018-01-27 19:09:28 -0500146 * \param req request object containing the face creation parameters
147 * \param onCreated callback if face creation succeeds or face already exists; the settings
148 * of an existing face are not updated if they differ from the request
Eric Newberryf40551a2016-09-05 15:41:16 -0700149 * \param onFailure callback if face creation fails
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800150 */
151 virtual void
Davide Pesavento15b55052018-01-27 19:09:28 -0500152 createFace(const CreateFaceRequest& req,
Alexander Afanasyevd6655302014-02-28 08:41:28 -0800153 const FaceCreatedCallback& onCreated,
Eric Newberryf40551a2016-09-05 15:41:16 -0700154 const FaceCreationFailedCallback& onFailure) = 0;
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600155
Davide Pesavento1d7e7af2015-10-10 23:54:08 +0200156 virtual std::vector<shared_ptr<const Channel>>
Steve DiBenedettoef04f272014-06-04 14:28:31 -0600157 getChannels() const = 0;
Junxiao Shi38b24c72017-01-05 02:59:31 +0000158
159protected:
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000160 explicit
161 ProtocolFactory(const CtorParams& params);
162
Junxiao Shi38b24c72017-01-05 02:59:31 +0000163 template<typename ChannelMap>
164 static std::vector<shared_ptr<const Channel>>
165 getChannelsFromMap(const ChannelMap& channelMap)
166 {
167 std::vector<shared_ptr<const Channel>> channels;
168 boost::copy(channelMap | boost::adaptors::map_values, std::back_inserter(channels));
169 return channels;
170 }
171
Junxiao Shib47247d2017-01-24 15:09:16 +0000172private: // registry
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000173 using CreateFunc = std::function<unique_ptr<ProtocolFactory>(const CtorParams&)>;
174 using Registry = std::map<std::string, CreateFunc>; // indexed by factory id
Junxiao Shib47247d2017-01-24 15:09:16 +0000175
176 static Registry&
177 getRegistry();
178
Junxiao Shi38b24c72017-01-05 02:59:31 +0000179protected:
Junxiao Shi2d491752017-07-14 21:32:05 +0000180 std::set<std::string> providedSchemes; ///< FaceUri schemes provided by this ProtocolFactory
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000181 FaceCreatedCallback addFace; ///< callback when a new face is created
182
Junxiao Shi2d491752017-07-14 21:32:05 +0000183 /** \brief NetworkMonitor for listing available network interfaces and monitoring their changes
184 *
185 * ProtocolFactory subclass should check the NetworkMonitor has sufficient capabilities prior
186 * to usage.
Junxiao Shi38b24c72017-01-05 02:59:31 +0000187 */
Junxiao Shi2d491752017-07-14 21:32:05 +0000188 shared_ptr<ndn::net::NetworkMonitor> netmon;
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800189};
190
Junxiao Shi38b24c72017-01-05 02:59:31 +0000191} // namespace face
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800192} // namespace nfd
Alexander Afanasyeva9034b02014-01-26 18:32:02 -0800193
Junxiao Shib47247d2017-01-24 15:09:16 +0000194/** \brief registers a protocol factory
195 *
196 * This macro should appear once in .cpp of each protocol factory.
197 */
198#define NFD_REGISTER_PROTOCOL_FACTORY(PF) \
199static class NfdAuto ## PF ## ProtocolFactoryRegistrationClass \
200{ \
201public: \
202 NfdAuto ## PF ## ProtocolFactoryRegistrationClass() \
203 { \
204 ::nfd::face::ProtocolFactory::registerType<PF>(); \
205 } \
206} g_nfdAuto ## PF ## ProtocolFactoryRegistrationVariable
207
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700208#endif // NFD_DAEMON_FACE_PROTOCOL_FACTORY_HPP