blob: 0bfc9808d460072826a06ae7361f5c4b6cb55e7f [file] [log] [blame]
Junxiao Shi05dd4442017-02-06 22:50:07 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev0c63c632017-12-05 11:17:09 -05002/*
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, Regents of the University of California,
Junxiao Shi05dd4442017-02-06 22:50:07 +00004 * 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
Davide Pesavento990620a2022-06-05 00:25:53 -040026#include "face-helpers.hpp"
Junxiao Shi05dd4442017-02-06 22:50:07 +000027#include "format-helpers.hpp"
Davide Pesavento87fc0f82018-04-11 23:43:51 -040028
Davide Pesavento40641272023-03-16 13:31:12 -040029#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
Junxiao Shi05dd4442017-02-06 22:50:07 +000030#include <ndn-cxx/util/logger.hpp>
31
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040032namespace nfd::tools::nfdc {
Junxiao Shi05dd4442017-02-06 22:50:07 +000033
34NDN_LOG_INIT(nfdc.FindFace);
35
36FindFace::FindFace(ExecuteContext& ctx)
37 : m_ctx(ctx)
38{
39}
40
41FindFace::Code
42FindFace::execute(const FaceUri& faceUri, bool allowMulti)
43{
44 FaceQueryFilter filter;
45 filter.setRemoteUri(faceUri.toString());
Junxiao Shi084b7952017-02-26 22:00:53 +000046 return this->execute(filter, allowMulti);
Junxiao Shi05dd4442017-02-06 22:50:07 +000047}
48
49FindFace::Code
50FindFace::execute(uint64_t faceId)
51{
52 FaceQueryFilter filter;
53 filter.setFaceId(faceId);
54 return this->execute(filter);
55}
56
57FindFace::Code
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040058FindFace::execute(const std::any& faceIdOrUri, bool allowMulti)
Junxiao Shi918e5d42017-02-25 03:58:21 +000059{
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040060 const uint64_t* faceId = std::any_cast<uint64_t>(&faceIdOrUri);
Junxiao Shi918e5d42017-02-25 03:58:21 +000061 if (faceId != nullptr) {
62 return this->execute(*faceId);
63 }
64 else {
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040065 return this->execute(std::any_cast<FaceUri>(faceIdOrUri), allowMulti);
Junxiao Shi918e5d42017-02-25 03:58:21 +000066 }
67}
68
69FindFace::Code
Junxiao Shi05dd4442017-02-06 22:50:07 +000070FindFace::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()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070077 auto remoteUri = canonize("remote FaceUri", FaceUri(m_filter.getRemoteUri()));
Junxiao Shi05dd4442017-02-06 22:50:07 +000078 if (!remoteUri) {
Junxiao Shi05dd4442017-02-06 22:50:07 +000079 return m_res;
80 }
81 m_filter.setRemoteUri(remoteUri->toString());
82 }
83
Junxiao Shi36e54292017-02-17 18:43:16 +000084 if (m_filter.hasLocalUri()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070085 auto localUri = canonize("local FaceUri", FaceUri(m_filter.getLocalUri()));
Junxiao Shi36e54292017-02-17 18:43:16 +000086 if (!localUri) {
Junxiao Shi36e54292017-02-17 18:43:16 +000087 return m_res;
88 }
89 m_filter.setLocalUri(localUri->toString());
90 }
Junxiao Shi05dd4442017-02-06 22:50:07 +000091
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
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400106std::optional<FaceUri>
Eric Newberryd656aff2020-04-03 00:30:38 -0700107FindFace::canonize(const std::string& fieldName, const FaceUri& uri)
Junxiao Shi05dd4442017-02-06 22:50:07 +0000108{
Eric Newberryd656aff2020-04-03 00:30:38 -0700109 // 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;
Junxiao Shi05dd4442017-02-06 22:50:07 +0000113 }
114
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400115 auto [result, error] = nfdc::canonize(m_ctx, uri);
Eric Newberryd656aff2020-04-03 00:30:38 -0700116 if (result) {
117 // Canonization succeeded
118 return result;
119 }
120 else {
121 // Canonization failed
122 std::tie(m_res, m_errorReason) = canonizeErrorHelper(uri, error);
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400123 return std::nullopt;
Eric Newberryd656aff2020-04-03 00:30:38 -0700124 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000125}
126
127void
128FindFace::query()
129{
Davide Pesavento990620a2022-06-05 00:25:53 -0400130 auto datasetCb = [this] (const auto& result) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000131 m_res = Code::OK;
132 m_results = result;
133 };
Davide Pesavento990620a2022-06-05 00:25:53 -0400134 auto failureCb = [this] (uint32_t code, const auto& reason) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000135 m_res = Code::ERROR;
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -0500136 m_errorReason = "Error " + std::to_string(code) + " when querying face: " + reason;
Junxiao Shi36e54292017-02-17 18:43:16 +0000137 };
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 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000147 m_ctx.face.processEvents();
148}
149
Junxiao Shi1d62e622017-03-08 22:39:28 +0000150std::set<uint64_t>
151FindFace::getFaceIds() const
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
Junxiao Shi05dd4442017-02-06 22:50:07 +0000160const FaceStatus&
161FindFace::getFaceStatus() const
162{
163 BOOST_ASSERT(m_results.size() == 1);
164 return m_results.front();
165}
166
167void
168FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
169{
170 text::Separator sep(" ", ", ");
171 for (const auto& item : m_results) {
172 os << sep;
173 switch (style) {
174 case DisambiguationStyle::LOCAL_URI:
175 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
176 break;
177 }
178 }
179}
180
Davide Pesavento990620a2022-06-05 00:25:53 -0400181std::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; },
Davide Pesaventoe277f8b2023-11-11 17:14:02 -0500189 ctx.face.getIoContext(), ctx.getTimeout());
Davide Pesavento990620a2022-06-05 00:25:53 -0400190 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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400208} // namespace nfd::tools::nfdc