blob: 93b896cc682632416ad12af0b12c3f2faf91e039 [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 Pesaventob7bfcb92022-05-22 23:55:23 -04003 * Copyright (c) 2014-2022, 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
Junxiao Shi05dd4442017-02-06 22:50:07 +000029#include <ndn-cxx/util/logger.hpp>
30
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::tools::nfdc {
Junxiao Shi05dd4442017-02-06 22:50:07 +000032
33NDN_LOG_INIT(nfdc.FindFace);
34
35FindFace::FindFace(ExecuteContext& ctx)
36 : m_ctx(ctx)
37{
38}
39
40FindFace::Code
41FindFace::execute(const FaceUri& faceUri, bool allowMulti)
42{
43 FaceQueryFilter filter;
44 filter.setRemoteUri(faceUri.toString());
Junxiao Shi084b7952017-02-26 22:00:53 +000045 return this->execute(filter, allowMulti);
Junxiao Shi05dd4442017-02-06 22:50:07 +000046}
47
48FindFace::Code
49FindFace::execute(uint64_t faceId)
50{
51 FaceQueryFilter filter;
52 filter.setFaceId(faceId);
53 return this->execute(filter);
54}
55
56FindFace::Code
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040057FindFace::execute(const std::any& faceIdOrUri, bool allowMulti)
Junxiao Shi918e5d42017-02-25 03:58:21 +000058{
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040059 const uint64_t* faceId = std::any_cast<uint64_t>(&faceIdOrUri);
Junxiao Shi918e5d42017-02-25 03:58:21 +000060 if (faceId != nullptr) {
61 return this->execute(*faceId);
62 }
63 else {
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040064 return this->execute(std::any_cast<FaceUri>(faceIdOrUri), allowMulti);
Junxiao Shi918e5d42017-02-25 03:58:21 +000065 }
66}
67
68FindFace::Code
Junxiao Shi05dd4442017-02-06 22:50:07 +000069FindFace::execute(const FaceQueryFilter& filter, bool allowMulti)
70{
71 BOOST_ASSERT(m_res == Code::NOT_STARTED);
72 m_res = Code::IN_PROGRESS;
73 m_filter = filter;
74
75 if (m_filter.hasRemoteUri()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070076 auto remoteUri = canonize("remote FaceUri", FaceUri(m_filter.getRemoteUri()));
Junxiao Shi05dd4442017-02-06 22:50:07 +000077 if (!remoteUri) {
Junxiao Shi05dd4442017-02-06 22:50:07 +000078 return m_res;
79 }
80 m_filter.setRemoteUri(remoteUri->toString());
81 }
82
Junxiao Shi36e54292017-02-17 18:43:16 +000083 if (m_filter.hasLocalUri()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070084 auto localUri = canonize("local FaceUri", FaceUri(m_filter.getLocalUri()));
Junxiao Shi36e54292017-02-17 18:43:16 +000085 if (!localUri) {
Junxiao Shi36e54292017-02-17 18:43:16 +000086 return m_res;
87 }
88 m_filter.setLocalUri(localUri->toString());
89 }
Junxiao Shi05dd4442017-02-06 22:50:07 +000090
91 this->query();
92 if (m_res == Code::OK) {
93 if (m_results.size() == 0) {
94 m_res = Code::NOT_FOUND;
95 m_errorReason = "Face not found";
96 }
97 else if (m_results.size() > 1 && !allowMulti) {
98 m_res = Code::AMBIGUOUS;
99 m_errorReason = "Multiple faces match the query";
100 }
101 }
102 return m_res;
103}
104
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400105std::optional<FaceUri>
Eric Newberryd656aff2020-04-03 00:30:38 -0700106FindFace::canonize(const std::string& fieldName, const FaceUri& uri)
Junxiao Shi05dd4442017-02-06 22:50:07 +0000107{
Eric Newberryd656aff2020-04-03 00:30:38 -0700108 // We use a wrapper because we want to accept FaceUris that cannot be canonized
109 if (!FaceUri::canCanonize(uri.getScheme())) {
110 NDN_LOG_DEBUG("Using " << fieldName << "=" << uri << " without canonization");
111 return uri;
Junxiao Shi05dd4442017-02-06 22:50:07 +0000112 }
113
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400114 auto [result, error] = nfdc::canonize(m_ctx, uri);
Eric Newberryd656aff2020-04-03 00:30:38 -0700115 if (result) {
116 // Canonization succeeded
117 return result;
118 }
119 else {
120 // Canonization failed
121 std::tie(m_res, m_errorReason) = canonizeErrorHelper(uri, error);
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400122 return std::nullopt;
Eric Newberryd656aff2020-04-03 00:30:38 -0700123 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000124}
125
126void
127FindFace::query()
128{
Davide Pesavento990620a2022-06-05 00:25:53 -0400129 auto datasetCb = [this] (const auto& result) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000130 m_res = Code::OK;
131 m_results = result;
132 };
Davide Pesavento990620a2022-06-05 00:25:53 -0400133 auto failureCb = [this] (uint32_t code, const auto& reason) {
Junxiao Shi36e54292017-02-17 18:43:16 +0000134 m_res = Code::ERROR;
Alexander Afanasyev0c63c632017-12-05 11:17:09 -0500135 m_errorReason = "Error " + to_string(code) + " when querying face: " + reason;
Junxiao Shi36e54292017-02-17 18:43:16 +0000136 };
137
138 if (m_filter.empty()) {
139 m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
140 datasetCb, failureCb, m_ctx.makeCommandOptions());
141 }
142 else {
143 m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
144 m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
145 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000146 m_ctx.face.processEvents();
147}
148
Junxiao Shi1d62e622017-03-08 22:39:28 +0000149std::set<uint64_t>
150FindFace::getFaceIds() const
151{
152 std::set<uint64_t> faceIds;
153 for (const FaceStatus& faceStatus : m_results) {
154 faceIds.insert(faceStatus.getFaceId());
155 }
156 return faceIds;
157}
158
Junxiao Shi05dd4442017-02-06 22:50:07 +0000159const FaceStatus&
160FindFace::getFaceStatus() const
161{
162 BOOST_ASSERT(m_results.size() == 1);
163 return m_results.front();
164}
165
166void
167FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
168{
169 text::Separator sep(" ", ", ");
170 for (const auto& item : m_results) {
171 os << sep;
172 switch (style) {
173 case DisambiguationStyle::LOCAL_URI:
174 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
175 break;
176 }
177 }
178}
179
Davide Pesavento990620a2022-06-05 00:25:53 -0400180std::pair<std::optional<FaceUri>, std::string>
181canonize(ExecuteContext& ctx, const FaceUri& uri)
182{
183 std::optional<FaceUri> result;
184 std::string error;
185 uri.canonize(
186 [&result] (const auto& canonicalUri) { result = canonicalUri; },
187 [&error] (const auto& errorReason) { error = errorReason; },
188 ctx.face.getIoService(), ctx.getTimeout());
189 ctx.face.processEvents();
190
191 return {result, error};
192}
193
194std::pair<FindFace::Code, std::string>
195canonizeErrorHelper(const FaceUri& uri,
196 const std::string& error,
197 const std::string& field)
198{
199 std::string msg = "Error during canonization of ";
200 if (!field.empty()) {
201 msg += field + " ";
202 }
203 msg += "'" + uri.toString() + "': " + error;
204 return {FindFace::Code::CANONIZE_ERROR, msg};
205}
206
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400207} // namespace nfd::tools::nfdc