find-face.cpp
Go to the documentation of this file.
1 /* -*- 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 
30 namespace nfd {
31 namespace tools {
32 namespace nfdc {
33 
34 NDN_LOG_INIT(nfdc.FindFace);
35 
37  : m_ctx(ctx)
38 {
39 }
40 
42 FindFace::execute(const FaceUri& faceUri, bool allowMulti)
43 {
44  FaceQueryFilter filter;
45  filter.setRemoteUri(faceUri.toString());
46  return this->execute(filter, allowMulti);
47 }
48 
50 FindFace::execute(uint64_t faceId)
51 {
52  FaceQueryFilter filter;
53  filter.setFaceId(faceId);
54  return this->execute(filter);
55 }
56 
58 FindFace::execute(const boost::any& faceIdOrUri, bool allowMulti)
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), allowMulti);
66  }
67 }
68 
70 FindFace::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 
85  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  }
93 
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 
108 ndn::optional<FaceUri>
109 FindFace::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 
128 void
129 FindFace::query()
130 {
131  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 " + 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  }
148  m_ctx.face.processEvents();
149 }
150 
151 std::set<uint64_t>
153 {
154  std::set<uint64_t> faceIds;
155  for (const FaceStatus& faceStatus : m_results) {
156  faceIds.insert(faceStatus.getFaceId());
157  }
158  return faceIds;
159 }
160 
161 const FaceStatus&
163 {
164  BOOST_ASSERT(m_results.size() == 1);
165  return m_results.front();
166 }
167 
168 void
170 {
171  text::Separator sep(" ", ", ");
172  for (const auto& item : m_results) {
173  os << sep;
174  switch (style) {
176  os << item.getFaceId() << " (local=" << item.getLocalUri() << ')';
177  break;
178  }
179  }
180 }
181 
182 } // namespace nfdc
183 } // namespace tools
184 } // namespace nfd
ndn::nfd::CommandOptions makeCommandOptions() const
FindFace(ExecuteContext &ctx)
Definition: find-face.cpp:36
context for command execution
NDN_LOG_INIT(nfdc.CommandDefinition)
time::nanoseconds getTimeout() const
found exactly one face, or found multiple faces when allowMulti is true
error during FaceUri canonization
found multiple faces and allowMulti is false
void printDisambiguation(std::ostream &os, DisambiguationStyle style) const
print results for disambiguation
Definition: find-face.cpp:169
Copyright (c) 2014-2015, Regents of the University of California, Arizona Board of Regents...
Definition: algorithm.hpp:32
Code execute(const FaceUri &faceUri, bool allowMulti=false)
find face by FaceUri
Definition: find-face.cpp:42
const FaceStatus & getFaceStatus() const
Definition: find-face.cpp:162
print different string on first and subsequent usage
std::set< uint64_t > getFaceIds() const
Definition: find-face.cpp:152