blob: d877e81e511d35454ccf630742cf88f10a71120e [file] [log] [blame]
Junxiao Shi05dd4442017-02-06 22:50:07 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2017, 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 "find-face.hpp"
27#include "format-helpers.hpp"
28#include <ndn-cxx/util/logger.hpp>
29
30namespace nfd {
31namespace tools {
32namespace nfdc {
33
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());
46 return this->execute(filter);
47}
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
Junxiao Shi918e5d42017-02-25 03:58:21 +000058FindFace::execute(const boost::any& faceIdOrUri)
59{
60 const uint64_t* faceId = boost::any_cast<uint64_t>(&faceIdOrUri);
61 if (faceId != nullptr) {
62 return this->execute(*faceId);
63 }
64 else {
65 return this->execute(boost::any_cast<FaceUri>(faceIdOrUri));
66 }
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()) {
77 auto remoteUri = this->canonize("remote", FaceUri(m_filter.getRemoteUri()));
78 if (!remoteUri) {
79 m_res = Code::CANONIZE_ERROR;
80 return m_res;
81 }
82 m_filter.setRemoteUri(remoteUri->toString());
83 }
84
Junxiao Shi36e54292017-02-17 18:43:16 +000085 if (m_filter.hasLocalUri()) {
86 auto localUri = this->canonize("local", FaceUri(m_filter.getLocalUri()));
87 if (!localUri) {
88 m_res = Code::CANONIZE_ERROR;
89 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
108ndn::optional<FaceUri>
109FindFace::canonize(const std::string& fieldName, const FaceUri& input)
110{
111 if (!FaceUri::canCanonize(input.getScheme())) {
112 NDN_LOG_DEBUG("Using " << fieldName << '=' << input << " without canonization");
113 return input;
114 }
115
116 ndn::optional<FaceUri> result;
117 input.canonize(
118 [&result] (const FaceUri& canonicalUri) { result = canonicalUri; },
119 [this, fieldName] (const std::string& errorReason) {
120 m_errorReason = "Error during " + fieldName + " FaceUri canonization: " + errorReason;
121 },
122 m_ctx.face.getIoService(), m_ctx.getTimeout());
123 m_ctx.face.processEvents();
124
125 return result;
126}
127
128void
129FindFace::query()
130{
Junxiao Shi36e54292017-02-17 18:43:16 +0000131 auto datasetCb = [this] (const std::vector<ndn::nfd::FaceStatus>& result) {
132 m_res = Code::OK;
133 m_results = result;
134 };
135 auto failureCb = [this] (uint32_t code, const std::string& reason) {
136 m_res = Code::ERROR;
137 m_errorReason = "Error " + std::to_string(code) + " when querying face: " + reason;
138 };
139
140 if (m_filter.empty()) {
141 m_ctx.controller.fetch<ndn::nfd::FaceDataset>(
142 datasetCb, failureCb, m_ctx.makeCommandOptions());
143 }
144 else {
145 m_ctx.controller.fetch<ndn::nfd::FaceQueryDataset>(
146 m_filter, datasetCb, failureCb, m_ctx.makeCommandOptions());
147 }
Junxiao Shi05dd4442017-02-06 22:50:07 +0000148 m_ctx.face.processEvents();
149}
150
151const FaceStatus&
152FindFace::getFaceStatus() const
153{
154 BOOST_ASSERT(m_results.size() == 1);
155 return m_results.front();
156}
157
158void
159FindFace::printDisambiguation(std::ostream& os, DisambiguationStyle style) const
160{
161 text::Separator sep(" ", ", ");
162 for (const auto& item : m_results) {
163 os << sep;
164 switch (style) {
165 case DisambiguationStyle::LOCAL_URI:
166 os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
167 break;
168 }
169 }
170}
171
172} // namespace nfdc
173} // namespace tools
174} // namespace nfd