blob: aba6c4f4f5a30c98f533e1da15ff6576175d8213 [file] [log] [blame]
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -08001/*
2 * jndn-management
3 * Copyright (c) 2015-2016, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 3, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 * more details.
13 */
14package com.intel.jndn.management;
15
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -080016import com.intel.jndn.management.enums.LocalControlHeader;
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080017import com.intel.jndn.management.enums.RouteOrigin;
18import com.intel.jndn.management.helpers.FetchHelper;
19import com.intel.jndn.management.helpers.StatusDatasetHelper;
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080020import com.intel.jndn.management.types.FaceStatus;
21import com.intel.jndn.management.types.FibEntry;
22import com.intel.jndn.management.types.ForwarderStatus;
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080023import com.intel.jndn.management.types.RibEntry;
24import com.intel.jndn.management.types.StrategyChoice;
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -080025import net.named_data.jndn.ControlParameters;
26import net.named_data.jndn.ControlResponse;
27import net.named_data.jndn.Data;
28import net.named_data.jndn.Face;
29import net.named_data.jndn.ForwardingFlags;
30import net.named_data.jndn.Interest;
31import net.named_data.jndn.KeyLocator;
32import net.named_data.jndn.Name;
33import net.named_data.jndn.encoding.EncodingException;
34import net.named_data.jndn.security.SecurityException;
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080035
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080036import java.io.IOException;
37import java.util.List;
38
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080039/**
40 * Helper class for interacting with an NDN forwarder daemon; see
41 * <a href="http://redmine.named-data.net/projects/nfd/wiki/Management">NFD Management</a>
42 * for explanations of the various protocols used.
43 *
44 * @author Andrew Brown <andrew.brown@intel.com>
45 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080046public final class Nfdc {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080047 private static final int OK_STATUS = 200;
48
49 /////////////////////////////////////////////////////////////////////////////
50
51 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080052 * Prevent creation of Nfdc instances.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080053 */
54 private Nfdc() {
55 }
56
57 /**
58 * Retrieve the status of the given forwarder; calls /localhost/nfd/status/general
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080059 * which requires a local Face (all non-local packets are dropped).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080060 *
61 * @param face only a localhost Face
62 * @return the forwarder status object
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080063 * @throws ManagementException if the network request failed or the returned status could not be decoded
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080064 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus">ForwarderStatus</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080065 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080066 public static ForwarderStatus getForwarderStatus(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080067 try {
68 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/status/general"));
69 return new ForwarderStatus(StatusDatasetHelper.combine(segments));
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080070 } catch (IOException | EncodingException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080071 throw new ManagementException(e.getMessage(), e);
72 }
73 }
74
75 /**
76 * Retrieve a list of faces and their status from the given forwarder; calls
77 * /localhost/nfd/faces/list which requires a local Face (all non-local
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080078 * packets are dropped).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080079 *
80 * @param face only a localhost Face
81 * @return a list of face status objects
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080082 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080083 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">FaceManagement</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080084 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080085 public static List<FaceStatus> getFaceList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080086 try {
87 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/faces/list"));
88 return StatusDatasetHelper.wireDecode(segments, FaceStatus.class);
89 } catch (IOException e) {
90 throw new ManagementException(e.getMessage(), e);
91 }
92 }
93
94 /**
95 * Retrieve a list of FIB entries and their NextHopRecords from the given
96 * forwarder; calls /localhost/nfd/fib/list which requires a local Face (all
97 * non-local packets are dropped).
98 *
99 * @param face only a localhost Face
100 * @return a list of FIB entries
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800101 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800102 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#FIB-Dataset">FIB Dataset</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800103 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800104 public static List<FibEntry> getFibList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800105 try {
106 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/fib/list"));
107 return StatusDatasetHelper.wireDecode(segments, FibEntry.class);
108 } catch (IOException e) {
109 throw new ManagementException(e.getMessage(), e);
110 }
111 }
112
113 /**
114 * Retrieve a list of routing entries from the RIB; calls
115 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
116 * are dropped).
117 *
118 * @param face only a localhost Face
119 * @return a list of RIB entries, i.e. routes
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800120 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800121 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#RIB-Dataset">RIB Dataset</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800122 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800123 public static List<RibEntry> getRouteList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800124 try {
125 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/rib/list"));
126 return StatusDatasetHelper.wireDecode(segments, RibEntry.class);
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -0800127 } catch (ArrayIndexOutOfBoundsException | IOException e) {
128 // TODO: remove ArrayIndexOutOfBoundsException after fixing bug in MockFace
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800129 throw new ManagementException(e.getMessage(), e);
130 }
131 }
132
133 /**
134 * Retrieve the list of strategy choice entries from the NFD; calls
135 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
136 * are dropped).
137 *
138 * @param face only a localhost Face
139 * @return a list of strategy choice entries, i.e. routes
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800140 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
141 * the NFD rejected the request
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800142 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">StrategyChoice</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800143 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800144 public static List<StrategyChoice> getStrategyList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800145 try {
146 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/strategy-choice/list"));
147 return StatusDatasetHelper.wireDecode(segments, StrategyChoice.class);
148 } catch (IOException e) {
149 throw new ManagementException(e.getMessage(), e);
150 }
151 }
152
153 /**
154 * Retrieve the {@link KeyLocator} for an NFD.
155 *
156 * @param face only a localhost {@link Face}
157 * @return the {@link KeyLocator} of the NFD's key
158 * @throws ManagementException if the network request failed, if the NFD rejected the request, or no
159 * KeyLocator was found
160 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800161 public static KeyLocator getKeyLocator(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800162 try {
163 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/status/general"));
164 if (segments.isEmpty() || !KeyLocator.canGetFromSignature(segments.get(0).getSignature())) {
165 throw new ManagementException("No key locator available.");
166 }
167 return KeyLocator.getFromSignature(segments.get(0).getSignature());
168 } catch (IOException e) {
169 throw new ManagementException(e.getMessage(), e);
170 }
171 }
172
173 /**
174 * Create a new face on the given forwarder. Ensure the forwarding face is on
175 * the local machine (management requests are to /localhost/...) and that
176 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
177 *
178 * @param face only a localhost {@link Face}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800179 * @param uri a string like "tcp4://host.name.com" (see nfd-status channels
180 * for more protocol options)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800181 * @return the newly created face ID
182 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
183 * the NFD rejected the request
184 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800185 public static int createFace(final Face face, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800186 Name command = new Name("/localhost/nfd/faces/create");
187 ControlParameters parameters = new ControlParameters();
188 parameters.setUri(uri);
189 command.append(parameters.wireEncode());
190
191 try {
192 // send the interest
193 ControlResponse response = sendCommand(face, command);
194
195 // return
Alexander Afanasyev499aced2016-02-17 19:32:37 -0800196 return response.getBodyAsControlParameters().getFaceId();
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800197 } catch (IOException | EncodingException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800198 throw new ManagementException(e.getMessage(), e);
199 }
200 }
201
202 /**
203 * Destroy a face on given forwarder. Ensure the forwarding face is on the
204 * local machine (management requests are to /localhost/...) and that command
205 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
206 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800207 * @param face only a localhost {@link Face}
208 * @param faceId the ID of the face to destroy
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800209 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
210 * the NFD rejected the request
211 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800212 public static void destroyFace(final Face face, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800213 Name command = new Name("/localhost/nfd/faces/destroy");
214 ControlParameters parameters = new ControlParameters();
215 parameters.setFaceId(faceId);
216 command.append(parameters.wireEncode());
217
218 try {
219 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800220 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800221 throw new ManagementException(e.getMessage(), e);
222 }
223 }
224
225 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800226 * Enable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800227 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800228 * @param face only a localhost {@link Face}
229 * @param header the control feature to enable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800230 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
231 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800232 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800233 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800234 public static void enableLocalControlHeader(final Face face, final LocalControlHeader header) throws
235 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800236 // build command name
237 Name command = new Name("/localhost/nfd/faces/enable-local-control");
238 ControlParameters parameters = new ControlParameters();
239 parameters.setLocalControlFeature(header.toInteger());
240 command.append(parameters.wireEncode());
241
242 try {
243 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800244 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800245 throw new ManagementException(e.getMessage(), e);
246 }
247 }
248
249 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800250 * Disable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800251 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800252 * @param face only a localhost {@link Face}
253 * @param header the control feature to disable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800254 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
255 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800256 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800257 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800258 public static void disableLocalControlHeader(final Face face, final LocalControlHeader header) throws
259 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800260 // build command name
261 Name command = new Name("/localhost/nfd/faces/disable-local-control");
262 ControlParameters parameters = new ControlParameters();
263 parameters.setLocalControlFeature(header.toInteger());
264 command.append(parameters.wireEncode());
265
266 try {
267 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800268 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800269 throw new ManagementException(e.getMessage(), e);
270 }
271 }
272
273 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800274 * Register a route on the forwarder.
275 * <p/>
276 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800277 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
278 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800279 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800280 * @param controlParameters the {@link ControlParameters} command options
281 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
282 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800283 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
284 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800285 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800286 public static void register(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800287 // build command name
288 Name command = new Name("/localhost/nfd/rib/register");
289 command.append(controlParameters.wireEncode());
290
291 try {
292 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800293 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800294 throw new ManagementException(e.getMessage(), e);
295 }
296 }
297
298 /**
299 * Register a route on a forwarder; this will create a new face on the
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800300 * forwarder towards the face (e.g., self registration).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800301 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800302 * @param face only a localhost {@link Face}
303 * @param route the {@link Name} prefix of the route
304 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800305 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
306 * the NFD rejected the request
307 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800308 public static void register(final Face face, final Name route, final int cost) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800309 ForwardingFlags flags = new ForwardingFlags();
310 flags.setCapture(false);
311 flags.setChildInherit(true);
312
313 register(face, new ControlParameters()
314 .setName(route)
315 .setCost(cost)
316 .setOrigin(RouteOrigin.APP.toInteger())
317 .setForwardingFlags(flags));
318 }
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800319
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800320 /**
321 * Register a route on a forwarder; this will create a new face on the
322 * forwarder to the given URI/route pair. See register(Face,
323 * ControlParameters) for more detailed documentation.
324 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800325 * @param face only a localhost {@link Face}
326 * @param uri the URI (e.g. "tcp4://10.10.2.2:6363") of the remote node; note
327 * that this must be one of the canonical forms described in the wiki
328 * (http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#TCP) for NFD to
329 * accept the registration--otherwise you will see 400 errors
330 * @param route the {@link Name} prefix of the route
331 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800332 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
333 * the NFD rejected the request
334 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800335 public static void register(final Face face, final String uri, final Name route, final int cost) throws
336 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800337 // create the new face
338 int faceId = createFace(face, uri);
339
340 // run base method
341 register(face, faceId, route, cost);
342 }
343
344 /**
345 * Register a route on a forwarder; this will not create a new face since it
346 * is provided a faceId. See register(Face, ControlParameters) for full
347 * documentation.
348 *
349 * @param forwarder only a localhost {@link Face}
350 * @param faceId the ID of the {@link Face} to assign to the route
351 * @param route the {@link Name} prefix of the route
352 * @param cost the numeric cost of forwarding along the route
353 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
354 * the NFD rejected the request
355 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800356 public static void register(final Face forwarder, final int faceId, final Name route, final int cost) throws
357 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800358 // build command name
359 ControlParameters parameters = new ControlParameters();
360 parameters.setName(route);
361 parameters.setFaceId(faceId);
362 parameters.setCost(cost);
363 parameters.setOrigin(RouteOrigin.STATIC.toInteger());
364 ForwardingFlags flags = new ForwardingFlags();
365 flags.setCapture(false);
366 flags.setChildInherit(true);
367 parameters.setForwardingFlags(flags);
368
369 // run base method
370 register(forwarder, parameters);
371 }
372
373 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800374 * Unregister a route on a forwarder
375 * <p/>
376 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
377 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800378 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800379 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800380 * @param controlParameters the {@link ControlParameters} command options
381 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
382 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800383 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
384 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800385 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800386 public static void unregister(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800387 // build command name
388 Name command = new Name("/localhost/nfd/rib/unregister");
389 command.append(controlParameters.wireEncode());
390
391 try {
392 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800393 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800394 throw new ManagementException(e.getMessage(), e);
395 }
396 }
397
398 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800399 * Unregister a route on a forwarder.
400 * <p/>
401 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800402 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
403 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800404 * @param face only a localhost {@link Face}
405 * @param route the {@link Name} prefix of the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800406 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
407 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800408 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
409 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800410 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800411 public static void unregister(final Face face, final Name route) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800412 // build command name
413 ControlParameters controlParameters = new ControlParameters();
414 controlParameters.setName(route);
415
416 // send the interest
417 unregister(face, controlParameters);
418 }
419
420 /**
421 * Unregister a route on a forwarder; see
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800422 * <p/>
423 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800424 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
425 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800426 * @param face only a localhost {@link Face}
427 * @param route the {@link Name} prefix of the route
428 * @param faceId the specific ID of the face to remove (more than one face can
429 * be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800430 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
431 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800432 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
433 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800434 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800435 public static void unregister(final Face face, final Name route, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800436 // build command name
437 ControlParameters controlParameters = new ControlParameters();
438 controlParameters.setName(route);
439 controlParameters.setFaceId(faceId);
440
441 // send the interest
442 unregister(face, controlParameters);
443 }
444
445 /**
446 * Unregister a route on a forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800447 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800448 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
449 * signing has been set up using forwarder.setCommandSigningInfo().
450 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800451 * @param face only a localhost {@link Face}
452 * @param route the {@link Name} prefix of the route
453 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node (more
454 * than one face can be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800455 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
456 * the NFD rejected the request
457 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
458 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RibMgmt</a>
459 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800460 public static void unregister(final Face face, final Name route, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800461 int faceId = -1;
462 for (FaceStatus faceStatus : getFaceList(face)) {
463 if (faceStatus.getRemoteUri().matches(uri)) {
464 faceId = faceStatus.getFaceId();
465 break;
466 }
467 }
468
469 if (faceId == -1) {
470 throw new ManagementException("Face not found: " + uri);
471 }
472
473 // send the interest
474 unregister(face, route, faceId);
475 }
476
477 /**
478 * Set a strategy on the forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800479 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800480 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
481 * signing has been set up using forwarder.setCommandSigningInfo().
482 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800483 * @param face only a localhost {@link Face}
484 * @param prefix the {@link Name} prefix
485 * @param strategy the {@link Name} of the strategy to set, e.g.
486 * /localhost/nfd/strategy/broadcast
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800487 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
488 * the NFD rejected the request
489 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
490 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">StrategyChoice</a>
491 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800492 public static void setStrategy(final Face face, final Name prefix, final Name strategy) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800493 // build command name
494 Name command = new Name("/localhost/nfd/strategy-choice/set");
495 ControlParameters parameters = new ControlParameters();
496 parameters.setName(prefix);
497 parameters.setStrategy(strategy);
498 command.append(parameters.wireEncode());
499
500 try {
501 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800502 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800503 throw new ManagementException(e.getMessage(), e);
504 }
505 }
506
507 /**
508 * Set a strategy on the forwarder; see
509 * {@link #setStrategy(net.named_data.jndn.Face, net.named_data.jndn.Name, net.named_data.jndn.Name)}
510 * for more information. Ensure the forwarding face is on the local machine
511 * (management requests are to /localhost/...) and that command signing has
512 * been set up (e.g. forwarder.setCommandSigningInfo()).
513 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800514 * @param face only a localhost {@link Face}
515 * @param prefix the {@link Name} prefix
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800516 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
517 * the NFD rejected the request
518 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800519 public static void unsetStrategy(final Face face, final Name prefix) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800520 // build command name
521 Name command = new Name("/localhost/nfd/strategy-choice/unset");
522 ControlParameters parameters = new ControlParameters();
523 parameters.setName(prefix);
524 command.append(parameters.wireEncode());
525
526 try {
527 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800528 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800529 throw new ManagementException(e.getMessage(), e);
530 }
531 }
532
533 /**
534 * Send an interest as a command to the forwarder; this method will convert
535 * the interest to a command interest and block until a response is received
536 * from the forwarder. Ensure the forwarding face is on the local machine
537 * (management requests are to /localhost/...) and that command signing has
538 * been set up (e.g. forwarder.setCommandSigningInfo()).
539 *
540 * @param face only a localhost Face, command signing info must be set
541 * @param name As described at
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800542 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ControlCommand">ControlCommand</a>,
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800543 * the requested interest must have encoded ControlParameters appended to the
544 * interest name
545 * @return a {@link ControlResponse}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800546 * @throws IOException if the network request failed
547 * @throws EncodingException if the NFD response could not be decoded
548 * @throws ManagementException if the NFD rejected the request
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800549 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800550 private static ControlResponse sendCommand(final Face face, final Name name) throws IOException, EncodingException,
551 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800552 Interest interest = new Interest(name);
553
554 // forwarder must have command signing info set
555 try {
556 face.makeCommandInterest(interest);
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -0800557 } catch (NullPointerException | SecurityException e) {
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800558 throw new IllegalArgumentException("Failed to make command interest; ensure command signing info is set on the " +
559 "face.", e);
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800560 }
561
562 // send command packet
563 Data data = FetchHelper.getData(face, interest.getName());
564
565 // decode response
566 ControlResponse response = new ControlResponse();
567 response.wireDecode(data.getContent().buf());
568
569 // check response for success
570 if (response.getStatusCode() != OK_STATUS) {
571 throw ManagementException.fromResponse(response);
572 }
573
574 return response;
575 }
576}