blob: bb6183dfb70d3224fa9b0ac166447eb73dfd38d1 [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 Pesavento87fc0f82018-04-11 23:43:51 -04003 * Copyright (c) 2014-2018, 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"
27#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
31namespace nfd {
32namespace tools {
33namespace nfdc {
34
35NDN_LOG_INIT(nfdc.FindFace);
36
37FindFace::FindFace(ExecuteContext& ctx)
38 : m_ctx(ctx)
39{
40}
41
42FindFace::Code
43FindFace::execute(const FaceUri& faceUri, bool allowMulti)
44{
45 FaceQueryFilter filter;
46 filter.setRemoteUri(faceUri.toString());
Junxiao Shi084b7952017-02-26 22:00:53 +000047 return this->execute(filter, allowMulti);
Junxiao Shi05dd4442017-02-06 22:50:07 +000048}
49
50FindFace::Code
51FindFace::execute(uint64_t faceId)
52{
53 FaceQueryFilter filter;
54 filter.setFaceId(faceId);
55 return this->execute(filter);
56}
57
58FindFace::Code
Davide Pesavento8b663a92018-11-21 22:57:20 -050059FindFace::execute(const ndn::any& faceIdOrUri, bool allowMulti)
Junxiao Shi918e5d42017-02-25 03:58:21 +000060{
Davide Pesavento8b663a92018-11-21 22:57:20 -050061 const uint64_t* faceId = ndn::any_cast<uint64_t>(&faceIdOrUri);
Junxiao Shi918e5d42017-02-25 03:58:21 +000062 if (faceId != nullptr) {
63 return this->execute(*faceId);
64 }
65 else {
Davide Pesavento8b663a92018-11-21 22:57:20 -050066 return this->execute(ndn::any_cast<FaceUri>(faceIdOrUri), allowMulti);
Junxiao Shi918e5d42017-02-25 03:58:21 +000067 }
68}
69
70FindFace::Code
Junxiao Shi05dd4442017-02-06 22:50:07 +000071FindFace::execute(const FaceQueryFilter& filter, bool allowMulti)
72{
73 BOOST_ASSERT(m_res == Code::NOT_STARTED);
74 m_res = Code::IN_PROGRESS;
75 m_filter = filter;
76
77 if (m_filter.hasRemoteUri()) {
78 auto remoteUri = this->canonize("remote", FaceUri(m_filter.getRemoteUri()));
79 if (!remoteUri) {
80 m_res = Code::CANONIZE_ERROR;
81 return m_res;
82 }
83 m_filter.setRemoteUri(remoteUri->toString());
84 }
85
Junxiao Shi36e54292017-02-17 18:43:16 +000086 if (m_filter.hasLocalUri()) {
87 auto localUri = this->canonize("local", FaceUri(m_filter.getLocalUri()));
88 if (!localUri) {
89 m_res = Code::CANONIZE_ERROR;
90 return m_res;
91 }
92 m_filter.setLocalUri(localUri->toString());
93 }
Junxiao Shi05dd4442017-02-06 22:50:07 +000094
95 this->query();
96 if (m_res == Code::OK) {
97 if (m_results.size() == 0) {
98 m_res = Code::NOT_FOUND;
99 m_errorReason = "Face not found";
100 }
101 else if (m_results.size() > 1 && !allowMulti) {
102 m_res = Code::AMBIGUOUS;
103 m_errorReason = "Multiple faces match the query";
104 }
105 }
106 return m_res;
107}
108
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400109optional<FaceUri>
Junxiao Shi05dd4442017-02-06 22:50:07 +0000110FindFace::canonize(const std::string& fieldName, const FaceUri& input)
111{
112 if (!FaceUri::canCanonize(input.getScheme())) {
113 NDN_LOG_DEBUG("Using " << fieldName << '=' << input << " without canonization");
114 return input;
115 }
116
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400117 optional<FaceUri> result;
Junxiao Shi05dd4442017-02-06 22:50:07 +0000118 input.canonize(
119 [&result] (const FaceUri& canonicalUri) { result = canonicalUri; },
120 [this, fieldName] (const std::string& errorReason) {
121 m_errorReason = "Error during " + fieldName + " FaceUri canonization: " + errorReason;
122 },
123 m_ctx.face.getIoService(), m_ctx.getTimeout());
124 m_ctx.face.processEvents();
125
126 return result;
127}
128
129void
130FindFace::query()
131{
Junxiao Shi36e54292017-02-17 18:43:16 +0000132 auto datasetCb = [this] (const std::vector<ndn::nfd::FaceStatus>& result) {
133 m_res = Code::OK;
134 m_results = result;
135 };
136 auto failureCb = [this] (uint32_t code, const std::string& reason) {
137 m_res = Code::ERROR;
Alexander Afanasyev0c63c632017-12-05 11:17:09 -0500138 m_errorReason = "Error " + to_string(code) + " when querying face: " + reason;
Junxiao Shi36e54292017-02-17 18:43:16 +0000139 };
140
141 if (m_filter.empty()) {
142 m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
143 datasetCb, failureCb, m_ctx.makeCommandOptions());
144 }
145 else {
146 m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
147 m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
148 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000149 m_ctx.face.processEvents();
150}
151
Junxiao Shi1d62e622017-03-08 22:39:28 +0000152std::set<uint64_t>
153FindFace::getFaceIds() const
154{
155 std::set<uint64_t> faceIds;
156 for (const FaceStatus& faceStatus : m_results) {
157 faceIds.insert(faceStatus.getFaceId());
158 }
159 return faceIds;
160}
161
Junxiao Shi05dd4442017-02-06 22:50:07 +0000162const FaceStatus&
163FindFace::getFaceStatus() const
164{
165 BOOST_ASSERT(m_results.size() == 1);
166 return m_results.front();
167}
168
169void
170FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
171{
172 text::Separator sep(" ", ", ");
173 for (const auto& item : m_results) {
174 os << sep;
175 switch (style) {
176 case DisambiguationStyle::LOCAL_URI:
177 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
178 break;
179 }
180 }
181}
182
183} // namespace nfdc
184} // namespace tools
185} // namespace nfd