blob: 05e7eecce9cca27df9803c0f2dddbd42eb5c8190 [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
26#include "find-face.hpp"
Eric Newberryd656aff2020-04-03 00:30:38 -070027#include "canonizer.hpp"
Junxiao Shi05dd4442017-02-06 22:50:07 +000028#include "format-helpers.hpp"
Davide Pesavento87fc0f82018-04-11 23:43:51 -040029
Junxiao Shi05dd4442017-02-06 22:50:07 +000030#include <ndn-cxx/util/logger.hpp>
31
32namespace nfd {
33namespace tools {
34namespace nfdc {
35
36NDN_LOG_INIT(nfdc.FindFace);
37
38FindFace::FindFace(ExecuteContext& ctx)
39 : m_ctx(ctx)
40{
41}
42
43FindFace::Code
44FindFace::execute(const FaceUri& faceUri, bool allowMulti)
45{
46 FaceQueryFilter filter;
47 filter.setRemoteUri(faceUri.toString());
Junxiao Shi084b7952017-02-26 22:00:53 +000048 return this->execute(filter, allowMulti);
Junxiao Shi05dd4442017-02-06 22:50:07 +000049}
50
51FindFace::Code
52FindFace::execute(uint64_t faceId)
53{
54 FaceQueryFilter filter;
55 filter.setFaceId(faceId);
56 return this->execute(filter);
57}
58
59FindFace::Code
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040060FindFace::execute(const std::any& faceIdOrUri, bool allowMulti)
Junxiao Shi918e5d42017-02-25 03:58:21 +000061{
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040062 const uint64_t* faceId = std::any_cast<uint64_t>(&faceIdOrUri);
Junxiao Shi918e5d42017-02-25 03:58:21 +000063 if (faceId != nullptr) {
64 return this->execute(*faceId);
65 }
66 else {
Davide Pesaventob7bfcb92022-05-22 23:55:23 -040067 return this->execute(std::any_cast<FaceUri>(faceIdOrUri), allowMulti);
Junxiao Shi918e5d42017-02-25 03:58:21 +000068 }
69}
70
71FindFace::Code
Junxiao Shi05dd4442017-02-06 22:50:07 +000072FindFace::execute(const FaceQueryFilter& filter, bool allowMulti)
73{
74 BOOST_ASSERT(m_res == Code::NOT_STARTED);
75 m_res = Code::IN_PROGRESS;
76 m_filter = filter;
77
78 if (m_filter.hasRemoteUri()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070079 auto remoteUri = canonize("remote FaceUri", FaceUri(m_filter.getRemoteUri()));
Junxiao Shi05dd4442017-02-06 22:50:07 +000080 if (!remoteUri) {
Junxiao Shi05dd4442017-02-06 22:50:07 +000081 return m_res;
82 }
83 m_filter.setRemoteUri(remoteUri->toString());
84 }
85
Junxiao Shi36e54292017-02-17 18:43:16 +000086 if (m_filter.hasLocalUri()) {
Eric Newberryd656aff2020-04-03 00:30:38 -070087 auto localUri = canonize("local FaceUri", FaceUri(m_filter.getLocalUri()));
Junxiao Shi36e54292017-02-17 18:43:16 +000088 if (!localUri) {
Junxiao Shi36e54292017-02-17 18:43:16 +000089 return m_res;
90 }
91 m_filter.setLocalUri(localUri->toString());
92 }
Junxiao Shi05dd4442017-02-06 22:50:07 +000093
94 this->query();
95 if (m_res == Code::OK) {
96 if (m_results.size() == 0) {
97 m_res = Code::NOT_FOUND;
98 m_errorReason = "Face not found";
99 }
100 else if (m_results.size() > 1 && !allowMulti) {
101 m_res = Code::AMBIGUOUS;
102 m_errorReason = "Multiple faces match the query";
103 }
104 }
105 return m_res;
106}
107
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400108std::optional<FaceUri>
Eric Newberryd656aff2020-04-03 00:30:38 -0700109FindFace::canonize(const std::string& fieldName, const FaceUri& uri)
Junxiao Shi05dd4442017-02-06 22:50:07 +0000110{
Eric Newberryd656aff2020-04-03 00:30:38 -0700111 // We use a wrapper because we want to accept FaceUris that cannot be canonized
112 if (!FaceUri::canCanonize(uri.getScheme())) {
113 NDN_LOG_DEBUG("Using " << fieldName << "=" << uri << " without canonization");
114 return uri;
Junxiao Shi05dd4442017-02-06 22:50:07 +0000115 }
116
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400117 std::optional<FaceUri> result;
Eric Newberryd656aff2020-04-03 00:30:38 -0700118 std::string error;
119 std::tie(result, error) = nfdc::canonize(m_ctx, uri);
Junxiao Shi05dd4442017-02-06 22:50:07 +0000120
Eric Newberryd656aff2020-04-03 00:30:38 -0700121 if (result) {
122 // Canonization succeeded
123 return result;
124 }
125 else {
126 // Canonization failed
127 std::tie(m_res, m_errorReason) = canonizeErrorHelper(uri, error);
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400128 return std::nullopt;
Eric Newberryd656aff2020-04-03 00:30:38 -0700129 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000130}
131
132void
133FindFace::query()
134{
Junxiao Shi36e54292017-02-17 18:43:16 +0000135 auto datasetCb = [this] (const std::vector<ndn::nfd::FaceStatus>& result) {
136 m_res = Code::OK;
137 m_results = result;
138 };
139 auto failureCb = [this] (uint32_t code, const std::string& reason) {
140 m_res = Code::ERROR;
Alexander Afanasyev0c63c632017-12-05 11:17:09 -0500141 m_errorReason = "Error " + to_string(code) + " when querying face: " + reason;
Junxiao Shi36e54292017-02-17 18:43:16 +0000142 };
143
144 if (m_filter.empty()) {
145 m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
146 datasetCb, failureCb, m_ctx.makeCommandOptions());
147 }
148 else {
149 m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
150 m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
151 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000152 m_ctx.face.processEvents();
153}
154
Junxiao Shi1d62e622017-03-08 22:39:28 +0000155std::set<uint64_t>
156FindFace::getFaceIds() const
157{
158 std::set<uint64_t> faceIds;
159 for (const FaceStatus& faceStatus : m_results) {
160 faceIds.insert(faceStatus.getFaceId());
161 }
162 return faceIds;
163}
164
Junxiao Shi05dd4442017-02-06 22:50:07 +0000165const FaceStatus&
166FindFace::getFaceStatus() const
167{
168 BOOST_ASSERT(m_results.size() == 1);
169 return m_results.front();
170}
171
172void
173FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
174{
175 text::Separator sep(" ", ", ");
176 for (const auto& item : m_results) {
177 os << sep;
178 switch (style) {
179 case DisambiguationStyle::LOCAL_URI:
180 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
181 break;
182 }
183 }
184}
185
186} // namespace nfdc
187} // namespace tools
188} // namespace nfd