blob: 2578713def170285fd6fbea89aba0037dcef795d [file] [log] [blame]
Andrew Brown2f1fdbf2015-01-21 10:52:29 -08001/*
andrewsbrown7e6b9e82015-03-03 16:11:11 -08002 * jndn-management
3 * Copyright (c) 2015, 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.
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080013 */
14package com.intel.jndn.management;
15
Andrew Brownc46c1602015-02-18 10:45:56 -080016import com.intel.jndn.management.types.StatusDataset;
17import com.intel.jndn.management.types.ControlResponse;
18import com.intel.jndn.management.types.FaceStatus;
Andrew Brown63bed362015-02-18 11:28:50 -080019import com.intel.jndn.management.types.FibEntry;
andrewsbrowne8e8e852015-03-09 13:48:31 -070020import com.intel.jndn.management.types.LocalControlHeader;
Andrew Brownc46c1602015-02-18 10:45:56 -080021import com.intel.jndn.management.types.RibEntry;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080022import com.intel.jndn.utils.Client;
Andrew Brown07466442015-02-24 09:07:02 -080023import com.intel.jndn.utils.SegmentedClient;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080024import java.io.IOException;
25import java.util.List;
26import net.named_data.jndn.ControlParameters;
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.Name;
32import net.named_data.jndn.encoding.EncodingException;
33import net.named_data.jndn.security.SecurityException;
Andrew Brownc46c1602015-02-18 10:45:56 -080034import java.util.logging.Logger;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080035
36/**
37 * Helper class for interacting with an NDN forwarder daemon; see
38 * http://redmine.named-data.net/projects/nfd/wiki/Management for explanations
39 * of the various protocols used.
40 *
41 * @author Andrew Brown <andrew.brown@intel.com>
42 */
43public class NFD {
44
Andrew Brown211d2b62015-02-18 11:12:02 -080045 public final static long DEFAULT_TIMEOUT = 2000;
46 static private final Logger logger = Logger.getLogger(NFD.class.getName());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080047
Andrew Brown211d2b62015-02-18 11:12:02 -080048 /**
49 * Ping a forwarder on an existing face to verify that the forwarder is
50 * working and responding to requests; this version sends a discovery packet
51 * to /localhost/nfd which should always respond if the requestor is on the
52 * same machine as the NDN forwarding daemon.
53 *
54 * @param face
55 * @return true if successful, false otherwise
56 */
57 public static boolean pingLocal(Face face) {
58 return ping(face, new Name("/localhost/nfd"));
59 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080060
Andrew Brown211d2b62015-02-18 11:12:02 -080061 /**
62 * Request a name on an existing face to verify the forwarder is working and
63 * responding to requests. Note that the name must be served or cached on the
64 * forwarder for this to return true.
65 *
66 * @param face
67 * @param name
68 * @return true if successful, false otherwise
69 */
70 public static boolean ping(Face face, Name name) {
71 // build interest
72 Interest interest = new Interest(name);
73 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
74 interest.setMustBeFresh(true);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080075
Andrew Brown211d2b62015-02-18 11:12:02 -080076 // send packet
77 Data data = Client.getDefault().getSync(face, interest);
78 return data != null;
79 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080080
Andrew Brown211d2b62015-02-18 11:12:02 -080081 /**
82 * Retrieve a list of faces and their status from the given forwarder; calls
83 * /localhost/nfd/faces/list which requires a local Face (all non-local
84 * packets are dropped)
85 *
86 * @param forwarder Only a localhost Face
87 * @return
88 * @throws Exception
89 */
90 public static List<FaceStatus> getFaceList(Face forwarder) throws Exception {
91 // build management Interest packet; see http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
92 Interest interest = new Interest(new Name("/localhost/nfd/faces/list"));
93 interest.setMustBeFresh(true);
94 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
95 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080096
Andrew Brown211d2b62015-02-18 11:12:02 -080097 // send packet
Andrew Brown07466442015-02-24 09:07:02 -080098 Data data = SegmentedClient.getDefault().getSync(forwarder, interest);
Andrew Brown211d2b62015-02-18 11:12:02 -080099 if (data == null) {
100 throw new Exception("Failed to retrieve list of faces from the forwarder.");
101 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800102
andrewsbrown4c21ea22015-03-09 12:05:03 -0700103 // check for failed request
104 if (data.getContent().buf().get(0) == ControlResponse.TLV_CONTROL_RESPONSE) {
105 ControlResponse response = new ControlResponse();
106 response.wireDecode(data.getContent().buf());
107 throw new Exception("Failed to retrieve list of faces, forwarder returned: " + response.getStatusCode() + " " + response.getStatusText());
108 }
109
Andrew Brown211d2b62015-02-18 11:12:02 -0800110 // parse packet
111 return StatusDataset.wireDecode(data.getContent(), FaceStatus.class);
112 }
Andrew Brownc46c1602015-02-18 10:45:56 -0800113
Andrew Brown211d2b62015-02-18 11:12:02 -0800114 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800115 * Retrieve a list of FIB entries and their NextHopRecords from the given
116 * forwarder; calls /localhost/nfd/fib/list which requires a local Face (all
117 * non-local packets are dropped).
118 *
119 * @param forwarder Only a localhost Face
120 * @return
121 * @throws Exception
122 */
123 public static List<FibEntry> getFibList(Face forwarder) throws Exception {
124 // build management Interest packet; see http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
125 Interest interest = new Interest(new Name("/localhost/nfd/fib/list"));
126 interest.setMustBeFresh(true);
127 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
128 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
129
130 // TODO verify that all faces are being returned; right now they don't
131 // match up with the results from nfd-status-http-server but no
132 // additional segments are present;
133 // see http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
134 // send packet
Andrew Brown07466442015-02-24 09:07:02 -0800135 Data data = SegmentedClient.getDefault().getSync(forwarder, interest);
Andrew Brown63bed362015-02-18 11:28:50 -0800136 if (data == null) {
andrewsbrown4c21ea22015-03-09 12:05:03 -0700137 throw new Exception("Failed to retrieve list of FIB entries from the forwarder.");
138 }
139
140 // check for failed request
141 if (data.getContent().buf().get(0) == ControlResponse.TLV_CONTROL_RESPONSE) {
142 ControlResponse response = new ControlResponse();
143 response.wireDecode(data.getContent().buf());
144 throw new Exception("Failed to retrieve list of FIB entries, forwarder returned: " + response.getStatusCode() + " " + response.getStatusText());
Andrew Brown63bed362015-02-18 11:28:50 -0800145 }
146
147 // parse packet
148 return StatusDataset.wireDecode(data.getContent(), FibEntry.class);
149 }
150
151 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800152 * Retrieve a list of routing entries from the RIB; calls
153 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
154 * are dropped)
155 *
156 * @param forwarder Only a localhost Face
157 * @return
158 * @throws Exception
159 */
160 public static List<RibEntry> getRouteList(Face forwarder) throws Exception {
161 // build management Interest packet; see http://redmine.named-data.net/projects/nfd/wiki/StatusDataset
162 Interest interest = new Interest(new Name("/localhost/nfd/rib/list"));
163 interest.setMustBeFresh(true);
164 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
165 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
Andrew Brownc46c1602015-02-18 10:45:56 -0800166
Andrew Brown211d2b62015-02-18 11:12:02 -0800167 // send packet
Andrew Brown07466442015-02-24 09:07:02 -0800168 Data data = SegmentedClient.getDefault().getSync(forwarder, interest);
Andrew Brown211d2b62015-02-18 11:12:02 -0800169 if (data == null) {
andrewsbrown4c21ea22015-03-09 12:05:03 -0700170 throw new Exception("Failed to retrieve list of routes from the forwarder.");
171 }
172
173 // check for failed request
174 if (data.getContent().buf().get(0) == ControlResponse.TLV_CONTROL_RESPONSE) {
175 ControlResponse response = new ControlResponse();
176 response.wireDecode(data.getContent().buf());
177 throw new Exception("Failed to retrieve list of routes, forwarder returned: " + response.getStatusCode() + " " + response.getStatusText());
Andrew Brown211d2b62015-02-18 11:12:02 -0800178 }
Andrew Brownc46c1602015-02-18 10:45:56 -0800179
Andrew Brown211d2b62015-02-18 11:12:02 -0800180 // parse packet
181 return StatusDataset.wireDecode(data.getContent(), RibEntry.class);
182 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800183
Andrew Brown211d2b62015-02-18 11:12:02 -0800184 /**
185 * Helper method to register a new face on the forwarder; as mentioned at
186 * http://named-data.net/doc/NFD/current/manpages/nfdc.html, this is more for
187 * debugging; use 'register' instead
188 *
189 * @param forwarder Only a localhost Face
190 * @param faceId
191 * @param prefix
192 * @return
193 * @throws Exception
194 */
195 public static boolean addNextHop(Face forwarder, int faceId, Name prefix) throws Exception {
196 // build command name
197 Name command = new Name("/localhost/nfd/fib/add-nexthop");
198 ControlParameters parameters = new ControlParameters();
199 parameters.setName(prefix);
200 parameters.setFaceId(faceId);
201 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800202
Andrew Brown211d2b62015-02-18 11:12:02 -0800203 // send the interest
204 return sendCommandAndErrorCheck(forwarder, new Interest(command));
205 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800206
Andrew Brown211d2b62015-02-18 11:12:02 -0800207 /**
208 * Create a new face on the given forwarder. Ensure the forwarding face is on
209 * the local machine (management requests are to /localhost/...) and that
210 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
211 *
212 * @param forwarder Only a localhost Face
213 * @param uri
214 * @return
215 * @throws java.lang.Exception
216 */
217 public static int createFace(Face forwarder, String uri) throws Exception {
218 Name command = new Name("/localhost/nfd/faces/create");
219 ControlParameters parameters = new ControlParameters();
220 parameters.setUri(uri);
221 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800222
Andrew Brown211d2b62015-02-18 11:12:02 -0800223 // send the interest
224 ControlResponse response = sendCommand(forwarder, new Interest(command));
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800225
Andrew Brown211d2b62015-02-18 11:12:02 -0800226 // check for body and that status code is OK (TODO: 200 should be replaced with a CONSTANT like ControlResponse.STATUS_OK)
227 if (response.getBody().isEmpty() || response.getStatusCode() != 200) {
228 throw new Exception("Failed to create face: " + uri + " " + response.getStatusText());
229 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800230
Andrew Brown211d2b62015-02-18 11:12:02 -0800231 // return
232 return response.getBody().get(0).getFaceId();
233 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800234
Andrew Brown211d2b62015-02-18 11:12:02 -0800235 /**
andrewsbrown4f209ba2015-03-16 16:07:28 -0700236 * Destroy a face on given forwarder. Ensure the forwarding face is on
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700237 * the local machine (management requests are to /localhost/...) and that
238 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
239 *
240 * @param forwarder Only a localhost Face
241 * @param faceId
andrewsbrown4f209ba2015-03-16 16:07:28 -0700242 * @return
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700243 * @throws java.lang.Exception
244 */
andrewsbrown4f209ba2015-03-16 16:07:28 -0700245 public static boolean destroyFace(Face forwarder, int faceId) throws Exception {
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700246 Name command = new Name("/localhost/nfd/faces/destroy");
247 ControlParameters parameters = new ControlParameters();
248 parameters.setFaceId(faceId);
249 command.append(parameters.wireEncode());
250
251 // send the interest
252 ControlResponse response = sendCommand(forwarder, new Interest(command));
253
254 // check for body and that status code is OK (TODO: 200 should be replaced with a CONSTANT like ControlResponse.STATUS_OK)
255 if (response.getBody().isEmpty() || response.getStatusCode() != 200) {
256 throw new Exception("Failed to destroy face: " + String.valueOf(faceId) + " " + response.getStatusText());
257 }
258
andrewsbrown4f209ba2015-03-16 16:07:28 -0700259 return true;
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700260 }
261
262 /**
andrewsbrowne8e8e852015-03-09 13:48:31 -0700263 * Enable a local control feature on the given forwarder. See
264 * http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature
265 *
266 * @param forwarder
267 * @param header
268 * @return
269 * @throws Exception
270 */
271 public static boolean enableLocalControlHeader(Face forwarder, LocalControlHeader header) throws Exception {
272 // build command name
273 Name command = new Name("/localhost/nfd/faces/enable-local-control");
274 ControlParameters parameters = new ControlParameters();
275 parameters.setLocalControlFeature(header.getNumericValue());
276 command.append(parameters.wireEncode());
277
278 // send command and return
279 return sendCommandAndErrorCheck(forwarder, new Interest(command));
280 }
281
282 /**
283 * Disable a local control feature on the given forwarder. See
284 * http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature
285 *
286 * @param forwarder
287 * @param header
288 * @return
289 * @throws Exception
290 */
291 public static boolean disableLocalControlHeader(Face forwarder, LocalControlHeader header) throws Exception {
292 // build command name
293 Name command = new Name("/localhost/nfd/faces/disable-local-control");
294 ControlParameters parameters = new ControlParameters();
295 parameters.setLocalControlFeature(header.getNumericValue());
296 command.append(parameters.wireEncode());
297
298 // send command and return
299 return sendCommandAndErrorCheck(forwarder, new Interest(command));
300 }
301
302 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800303 * Register a route on the forwarder; see
304 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
305 * usage and http://redmine.named-data.net/projects/nfd/wiki/RibMgmt for
306 * protocol documentation. Ensure the forwarding face is on the local machine
307 * (management requests are to /localhost/...) and that command signing has
308 * been set up (e.g. forwarder.setCommandSigningInfo()).
309 *
310 * @param forwarder Only a localhost Face
311 * @param controlParameters
312 * @return
313 * @throws Exception
314 */
315 public static boolean register(Face forwarder, ControlParameters controlParameters) throws Exception {
316 // build command name
317 Name command = new Name("/localhost/nfd/rib/register");
318 command.append(controlParameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800319
Andrew Brown211d2b62015-02-18 11:12:02 -0800320 // send the interest
321 return sendCommandAndErrorCheck(forwarder, new Interest(command));
322 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800323
Andrew Brown211d2b62015-02-18 11:12:02 -0800324 /**
325 * Register a route on a forwarder; this will create a new face on the
326 * forwarder to the given URI/route pair. See register(Face,
327 * ControlParameters) for more details documentation.
328 *
329 * @param forwarder Only a localhost Face
330 * @param uri
331 * @param cost
332 * @param route
333 * @return true for successful registration
334 * @throws java.lang.Exception
335 */
336 public static boolean register(Face forwarder, String uri, Name route, int cost) throws Exception {
337 // create the new face
338 int faceId = createFace(forwarder, uri);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800339
Andrew Brown211d2b62015-02-18 11:12:02 -0800340 // run base method
341 return register(forwarder, faceId, route, cost);
342 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800343
Andrew Brown211d2b62015-02-18 11:12:02 -0800344 /**
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 Face
350 * @param faceId
351 * @param route
352 * @param cost
353 * @return true for successful registration
354 * @throws java.lang.Exception
355 */
356 public static boolean register(Face forwarder, int faceId, Name route, int cost) throws Exception {
357 // build command name
358 ControlParameters parameters = new ControlParameters();
359 parameters.setName(route);
360 parameters.setFaceId(faceId);
361 parameters.setCost(cost);
362 ForwardingFlags flags = new ForwardingFlags();
363 flags.setCapture(true);
364 flags.setChildInherit(true);
365 parameters.setForwardingFlags(flags);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800366
Andrew Brown211d2b62015-02-18 11:12:02 -0800367 // run base method
368 return register(forwarder, parameters);
369 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800370
Andrew Brown211d2b62015-02-18 11:12:02 -0800371 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800372 * Unregister a route on a forwarder; see
373 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
374 * usage and http://redmine.named-data.net/projects/nfd/wiki/RibMgmt for
375 * protocol documentation. Ensure the forwarding face is on the local machine
376 * (management requests are to /localhost/...) and that command signing has
377 * been set up (e.g. forwarder.setCommandSigningInfo()
378 *
379 * @param forwarder
Andrew Brown07466442015-02-24 09:07:02 -0800380 * @param controlParameters
Andrew Brown63bed362015-02-18 11:28:50 -0800381 * @return
382 */
Andrew Brown07466442015-02-24 09:07:02 -0800383 public static boolean unregister(Face forwarder, ControlParameters controlParameters) throws Exception {
Andrew Brown63bed362015-02-18 11:28:50 -0800384 // build command name
385 Name command = new Name("/localhost/nfd/rib/unregister");
386 command.append(controlParameters.wireEncode());
387
388 // send the interest
389 return sendCommandAndErrorCheck(forwarder, new Interest(command));
390 }
391
392 /**
Andrew Brown07466442015-02-24 09:07:02 -0800393 * Unregister a route on a forwarder; see
394 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
395 * usage and http://redmine.named-data.net/projects/nfd/wiki/RibMgmt for
396 * protocol documentation. Ensure the forwarding face is on the local machine
397 * (management requests are to /localhost/...) and that command signing has
398 * been set up (e.g. forwarder.setCommandSigningInfo()
399 *
400 * @param forwarder
401 * @param route
402 * @return
403 */
404 public static boolean unregister(Face forwarder, Name route) throws Exception {
405 // build command name
406 ControlParameters controlParameters = new ControlParameters();
407 controlParameters.setName(route);
408
409 // send the interest
410 return unregister(forwarder, controlParameters);
411 }
412
413 /**
414 * Unregister a route on a forwarder; see
415 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
416 * usage and http://redmine.named-data.net/projects/nfd/wiki/RibMgmt for
417 * protocol documentation. Ensure the forwarding face is on the local machine
418 * (management requests are to /localhost/...) and that command signing has
419 * been set up (e.g. forwarder.setCommandSigningInfo()
420 *
421 * @param forwarder
422 * @param route
423 * @param faceId
424 * @return
425 */
426 public static boolean unregister(Face forwarder, Name route, int faceId) throws Exception {
427 // build command name
428 ControlParameters controlParameters = new ControlParameters();
429 controlParameters.setName(route);
430 controlParameters.setFaceId(faceId);
431
432 // send the interest
433 return unregister(forwarder, controlParameters);
434 }
435
436 /**
437 * Unregister a route on a forwarder; see
438 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
439 * usage and http://redmine.named-data.net/projects/nfd/wiki/RibMgmt for
440 * protocol documentation. Ensure the forwarding face is on the local machine
441 * (management requests are to /localhost/...) and that command signing has
442 * been set up (e.g. forwarder.setCommandSigningInfo()
443 *
444 * @param forwarder
445 * @param route
446 * @param uri
447 * @return
448 */
449 public static boolean unregister(Face forwarder, Name route, String uri) throws Exception {
450 int faceId = -1;
andrewsbrown4c21ea22015-03-09 12:05:03 -0700451 for (FaceStatus face : getFaceList(forwarder)) {
452 if (face.getUri().matches(uri)) {
Andrew Brown07466442015-02-24 09:07:02 -0800453 faceId = face.getFaceId();
454 break;
455 }
456 }
andrewsbrown4c21ea22015-03-09 12:05:03 -0700457
458 if (faceId == -1) {
Andrew Brown07466442015-02-24 09:07:02 -0800459 throw new Exception("Face not found: " + uri);
460 }
461
462 // send the interest
463 return unregister(forwarder, route, faceId);
464 }
465
466 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800467 * Set a strategy on the forwarder; see
468 * http://named-data.net/doc/NFD/current/manpages/nfdc.html for command-line
469 * usage and http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice
470 * for protocol documentation. Ensure the forwarding face is on the local
471 * machine (management requests are to /localhost/...) and that command
472 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
473 *
474 * @param forwarder Only a localhost Face
475 * @param prefix
476 * @param strategy
477 * @return true for successful command
478 * @throws Exception
479 */
480 public static boolean setStrategy(Face forwarder, Name prefix, Name strategy) throws Exception {
481 // build command name
482 Name command = new Name("/localhost/nfd/strategy-choice/set");
483 ControlParameters parameters = new ControlParameters();
484 parameters.setName(prefix);
485 parameters.setStrategy(strategy);
486 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800487
Andrew Brown211d2b62015-02-18 11:12:02 -0800488 // send the interest
489 return sendCommandAndErrorCheck(forwarder, new Interest(command));
490 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800491
Andrew Brown211d2b62015-02-18 11:12:02 -0800492 /**
493 * Send an interest as a command to the forwarder; this method will convert
494 * the interest to a command interest and block until a response is received
495 * from the forwarder. Ensure the forwarding face is on the local machine
496 * (management requests are to /localhost/...) and that command signing has
497 * been set up (e.g. forwarder.setCommandSigningInfo()).
498 *
499 * @param forwarder Only a localhost Face
500 * @param interest As described at
501 * http://redmine.named-data.net/projects/nfd/wiki/ControlCommand, the
502 * requested interest must have encoded ControlParameters appended to the
503 * interest name
504 * @return
505 * @throws net.named_data.jndn.security.SecurityException
506 * @throws java.io.IOException
507 * @throws net.named_data.jndn.encoding.EncodingException
508 */
509 public static ControlResponse sendCommand(Face forwarder, Interest interest) throws SecurityException, IOException, EncodingException {
510 forwarder.makeCommandInterest(interest);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800511
Andrew Brown211d2b62015-02-18 11:12:02 -0800512 // send command packet
513 Data data = Client.getDefault().getSync(forwarder, interest);
514 if (data == null) {
515 throw new IOException("Failed to receive command response.");
516 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800517
Andrew Brown211d2b62015-02-18 11:12:02 -0800518 // return response
519 ControlResponse response = new ControlResponse();
520 response.wireDecode(data.getContent().buf());
521 return response;
522 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800523
Andrew Brown211d2b62015-02-18 11:12:02 -0800524 /**
525 * Send an interest as a command to the forwarder; this method will convert
526 * the interest to a command interest and block until a response is received
527 * from the forwarder.
528 *
529 * @param forwarder Only a localhost Face
530 * @param interest As described at
531 * http://redmine.named-data.net/projects/nfd/wiki/ControlCommand, the
532 * requested interest must have encoded ControlParameters appended to the
533 * interest name
534 * @return
535 * @throws net.named_data.jndn.security.SecurityException
536 * @throws java.io.IOException
537 * @throws net.named_data.jndn.encoding.EncodingException
538 */
539 public static boolean sendCommandAndErrorCheck(Face forwarder, Interest interest) throws SecurityException, IOException, EncodingException {
540 ControlResponse response = sendCommand(forwarder, interest);
541 if (response.getStatusCode() < 400) {
542 return true;
543 } else {
544 logger.warning("Command sent but failed: " + response.getStatusCode() + " " + response.getStatusText());
545 return false;
546 }
547 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800548}