Loading...
Searching...
No Matches
face-helpers.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2024, Regents of the University of California,
4 * 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.
10 *
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/>.
24 */
25
26#include "face-helpers.hpp"
27#include "format-helpers.hpp"
28
29#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
30#include <ndn-cxx/util/logger.hpp>
31
32namespace nfd::tools::nfdc {
33
34NDN_LOG_INIT(nfdc.FindFace);
35
37 : m_ctx(ctx)
38{
39}
40
42FindFace::execute(const FaceUri& faceUri, bool allowMulti)
43{
44 FaceQueryFilter filter;
45 filter.setRemoteUri(faceUri.toString());
46 return this->execute(filter, allowMulti);
47}
48
50FindFace::execute(uint64_t faceId)
51{
52 FaceQueryFilter filter;
53 filter.setFaceId(faceId);
54 return this->execute(filter);
55}
56
58FindFace::execute(const std::any& faceIdOrUri, bool allowMulti)
59{
60 const uint64_t* faceId = std::any_cast<uint64_t>(&faceIdOrUri);
61 if (faceId != nullptr) {
62 return this->execute(*faceId);
63 }
64 else {
65 return this->execute(std::any_cast<FaceUri>(faceIdOrUri), allowMulti);
66 }
67}
68
70FindFace::execute(const FaceQueryFilter& filter, bool allowMulti)
71{
72 BOOST_ASSERT(m_res == Code::NOT_STARTED);
73 m_res = Code::IN_PROGRESS;
74 m_filter = filter;
75
76 if (m_filter.hasRemoteUri()) {
77 auto remoteUri = canonize("remote FaceUri", FaceUri(m_filter.getRemoteUri()));
78 if (!remoteUri) {
79 return m_res;
80 }
81 m_filter.setRemoteUri(remoteUri->toString());
82 }
83
84 if (m_filter.hasLocalUri()) {
85 auto localUri = canonize("local FaceUri", FaceUri(m_filter.getLocalUri()));
86 if (!localUri) {
87 return m_res;
88 }
89 m_filter.setLocalUri(localUri->toString());
90 }
91
92 this->query();
93 if (m_res == Code::OK) {
94 if (m_results.size() == 0) {
95 m_res = Code::NOT_FOUND;
96 m_errorReason = "Face not found";
97 }
98 else if (m_results.size() > 1 && !allowMulti) {
99 m_res = Code::AMBIGUOUS;
100 m_errorReason = "Multiple faces match the query";
101 }
102 }
103 return m_res;
104}
105
106std::optional<FaceUri>
107FindFace::canonize(const std::string& fieldName, const FaceUri& uri)
108{
109 // We use a wrapper because we want to accept FaceUris that cannot be canonized
110 if (!FaceUri::canCanonize(uri.getScheme())) {
111 NDN_LOG_DEBUG("Using " << fieldName << "=" << uri << " without canonization");
112 return uri;
113 }
114
115 auto [result, error] = nfdc::canonize(m_ctx, uri);
116 if (result) {
117 // Canonization succeeded
118 return result;
119 }
120 else {
121 // Canonization failed
122 std::tie(m_res, m_errorReason) = canonizeErrorHelper(uri, error);
123 return std::nullopt;
124 }
125}
126
127void
128FindFace::query()
129{
130 auto datasetCb = [this] (const auto& result) {
131 m_res = Code::OK;
132 m_results = result;
133 };
134 auto failureCb = [this] (uint32_t code, const auto& reason) {
135 m_res = Code::ERROR;
136 m_errorReason = "Error " + std::to_string(code) + " when querying face: " + reason;
137 };
138
139 if (m_filter.empty()) {
140 m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
141 datasetCb, failureCb, m_ctx.makeCommandOptions());
142 }
143 else {
144 m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
145 m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
146 }
147 m_ctx.face.processEvents();
148}
149
150std::set<uint64_t>
152{
153 std::set<uint64_t> faceIds;
154 for (const FaceStatus& faceStatus : m_results) {
155 faceIds.insert(faceStatus.getFaceId());
156 }
157 return faceIds;
158}
159
160const FaceStatus&
162{
163 BOOST_ASSERT(m_results.size() == 1);
164 return m_results.front();
165}
166
167void
169{
170 text::Separator sep(" ", ", ");
171 for (const auto& item : m_results) {
172 os << sep;
173 switch (style) {
175 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
176 break;
177 }
178 }
179}
180
181std::pair<std::optional<FaceUri>, std::string>
182canonize(ExecuteContext& ctx, const FaceUri& uri)
183{
184 std::optional<FaceUri> result;
185 std::string error;
186 uri.canonize(
187 [&result] (const auto& canonicalUri) { result = canonicalUri; },
188 [&error] (const auto& errorReason) { error = errorReason; },
189 ctx.face.getIoContext(), ctx.getTimeout());
190 ctx.face.processEvents();
191
192 return {result, error};
193}
194
195std::pair<FindFace::Code, std::string>
196canonizeErrorHelper(const FaceUri& uri,
197 const std::string& error,
198 const std::string& field)
199{
200 std::string msg = "Error during canonization of ";
201 if (!field.empty()) {
202 msg += field + " ";
203 }
204 msg += "'" + uri.toString() + "': " + error;
205 return {FindFace::Code::CANONIZE_ERROR, msg};
206}
207
208} // namespace nfd::tools::nfdc
Context for command execution.
ndn::nfd::Controller & controller
ndn::nfd::CommandOptions makeCommandOptions() const
ndn::time::nanoseconds getTimeout() const
std::set< uint64_t > getFaceIds() const
const FaceStatus & getFaceStatus() const
FindFace(ExecuteContext &ctx)
@ AMBIGUOUS
found multiple faces and allowMulti is false
@ CANONIZE_ERROR
error during FaceUri canonization
@ OK
found exactly one face, or found multiple faces when allowMulti is true
Code execute(const FaceUri &faceUri, bool allowMulti=false)
Find face by FaceUri.
void printDisambiguation(std::ostream &os, DisambiguationStyle style) const
Print results for disambiguation.
Print different string on first and subsequent usage.
std::pair< FindFace::Code, std::string > canonizeErrorHelper(const FaceUri &uri, const std::string &error, const std::string &field)
Helper to generate exit code and error message for face canonization failures.
std::pair< std::optional< FaceUri >, std::string > canonize(ExecuteContext &ctx, const FaceUri &uri)
Canonize a FaceUri.
NDN_LOG_INIT(nfdc.CommandDefinition)