blob: 937d0138b8b3af0aefff4178c526d30235a2d138 [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;
andrewsbrown8a32f302015-03-24 08:42:46 -070020import com.intel.jndn.management.types.ForwarderStatus;
andrewsbrowne8e8e852015-03-09 13:48:31 -070021import com.intel.jndn.management.types.LocalControlHeader;
Andrew Brownc46c1602015-02-18 10:45:56 -080022import com.intel.jndn.management.types.RibEntry;
andrewsbrown39b0fc92015-05-11 13:44:38 -070023import com.intel.jndn.management.types.StrategyChoice;
Andrew Brownbaf21d52015-07-13 10:32:46 -070024import com.intel.jndn.utils.client.SegmentedClient;
25import com.intel.jndn.utils.client.SimpleClient;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080026import java.io.IOException;
27import java.util.List;
28import net.named_data.jndn.ControlParameters;
29import net.named_data.jndn.Data;
30import net.named_data.jndn.Face;
31import net.named_data.jndn.ForwardingFlags;
32import net.named_data.jndn.Interest;
33import net.named_data.jndn.Name;
34import net.named_data.jndn.encoding.EncodingException;
35import net.named_data.jndn.security.SecurityException;
Andrew Brownc46c1602015-02-18 10:45:56 -080036import java.util.logging.Logger;
Andrew Brownc5dda702015-04-13 09:36:04 -070037import net.named_data.jndn.KeyLocator;
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080038
39/**
40 * Helper class for interacting with an NDN forwarder daemon; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -070041 * <a href="http://redmine.named-data.net/projects/nfd/wiki/Management">http://redmine.named-data.net/projects/nfd/wiki/Management</a>
42 * for explanations of the various protocols used.
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080043 *
44 * @author Andrew Brown <andrew.brown@intel.com>
45 */
46public class NFD {
47
Andrew Brown211d2b62015-02-18 11:12:02 -080048 public final static long DEFAULT_TIMEOUT = 2000;
andrewsbrown43b96302015-03-17 21:51:43 +010049 public final static int OK_STATUS = 200;
Andrew Brown211d2b62015-02-18 11:12:02 -080050 static private final Logger logger = Logger.getLogger(NFD.class.getName());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080051
Andrew Brown211d2b62015-02-18 11:12:02 -080052 /**
53 * Ping a forwarder on an existing face to verify that the forwarder is
54 * working and responding to requests; this version sends a discovery packet
55 * to /localhost/nfd which should always respond if the requestor is on the
56 * same machine as the NDN forwarding daemon.
57 *
andrewsbrown8a32f302015-03-24 08:42:46 -070058 * @param face only a localhost Face
Andrew Brown211d2b62015-02-18 11:12:02 -080059 * @return true if successful, false otherwise
60 */
61 public static boolean pingLocal(Face face) {
62 return ping(face, new Name("/localhost/nfd"));
63 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080064
Andrew Brown211d2b62015-02-18 11:12:02 -080065 /**
66 * Request a name on an existing face to verify the forwarder is working and
67 * responding to requests. Note that the name must be served or cached on the
68 * forwarder for this to return true.
69 *
andrewsbrowndb628382015-05-28 10:47:30 -070070 * @param face a {@link Face} to ping
71 * @param name a known {@link Name} that the remote node will answer to
Andrew Brown211d2b62015-02-18 11:12:02 -080072 * @return true if successful, false otherwise
73 */
74 public static boolean ping(Face face, Name name) {
75 // build interest
76 Interest interest = new Interest(name);
77 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
78 interest.setMustBeFresh(true);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080079
Andrew Brown211d2b62015-02-18 11:12:02 -080080 // send packet
andrewsbrown43b96302015-03-17 21:51:43 +010081 try {
82 Data data = SimpleClient.getDefault().getSync(face, interest);
83 return data != null;
84 } catch (IOException e) {
85 return false;
86 }
Andrew Brown211d2b62015-02-18 11:12:02 -080087 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -080088
Andrew Brown211d2b62015-02-18 11:12:02 -080089 /**
andrewsbrown8a32f302015-03-24 08:42:46 -070090 * Retrieve the status of the given forwarder; calls /localhost/nfd/status
91 * which requires a local Face (all non-local packets are dropped)
92 *
93 * @param forwarder only a localhost Face
94 * @return the forwarder status object, see
Andrew Browndfa8fc12015-03-25 10:46:47 -070095 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus">
96 * http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus</a>.
andrewsbrowndb628382015-05-28 10:47:30 -070097 * @throws IOException if the network request failed
98 * @throws EncodingException if the returned status could not be decoded
andrewsbrown8a32f302015-03-24 08:42:46 -070099 */
andrewsbrowndb628382015-05-28 10:47:30 -0700100 public static ForwarderStatus getForwarderStatus(Face forwarder) throws IOException, EncodingException {
Andrew Brownc5dda702015-04-13 09:36:04 -0700101 Data data = retrieveStatus(forwarder);
andrewsbrown8a32f302015-03-24 08:42:46 -0700102 ForwarderStatus status = new ForwarderStatus();
103 status.wireDecode(data.getContent().buf());
104 return status;
105 }
106
107 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800108 * Retrieve a list of faces and their status from the given forwarder; calls
109 * /localhost/nfd/faces/list which requires a local Face (all non-local
110 * packets are dropped)
111 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700112 * @param forwarder only a localhost Face
113 * @return a list of face status objects, see
114 * http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt.
andrewsbrowndb628382015-05-28 10:47:30 -0700115 * @throws IOException if the network request failed
116 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800117 */
andrewsbrowndb628382015-05-28 10:47:30 -0700118 public static List<FaceStatus> getFaceList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100119 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/faces/list"));
Andrew Brown211d2b62015-02-18 11:12:02 -0800120 return StatusDataset.wireDecode(data.getContent(), FaceStatus.class);
121 }
Andrew Brownc46c1602015-02-18 10:45:56 -0800122
Andrew Brown211d2b62015-02-18 11:12:02 -0800123 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800124 * Retrieve a list of FIB entries and their NextHopRecords from the given
125 * forwarder; calls /localhost/nfd/fib/list which requires a local Face (all
126 * non-local packets are dropped).
127 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700128 * @param forwarder only a localhost Face
129 * @return a list of FIB entries, see
130 * http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#FIB-Dataset.
andrewsbrowndb628382015-05-28 10:47:30 -0700131 * @throws IOException if the network request failed
132 * @throws ManagementException if the NFD rejected the request
Andrew Brown63bed362015-02-18 11:28:50 -0800133 */
andrewsbrowndb628382015-05-28 10:47:30 -0700134 public static List<FibEntry> getFibList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100135 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/fib/list"));
Andrew Brown63bed362015-02-18 11:28:50 -0800136 return StatusDataset.wireDecode(data.getContent(), FibEntry.class);
137 }
138
139 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800140 * Retrieve a list of routing entries from the RIB; calls
141 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
andrewsbrown43b96302015-03-17 21:51:43 +0100142 * are dropped).
Andrew Brown211d2b62015-02-18 11:12:02 -0800143 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700144 * @param forwarder only a localhost Face
145 * @return a list of RIB entries, i.e. routes, see
146 * http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#RIB-Dataset.
andrewsbrowndb628382015-05-28 10:47:30 -0700147 * @throws IOException if the network request failed
148 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800149 */
andrewsbrowndb628382015-05-28 10:47:30 -0700150 public static List<RibEntry> getRouteList(Face forwarder) throws IOException, ManagementException {
andrewsbrown43b96302015-03-17 21:51:43 +0100151 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/rib/list"));
Andrew Brown211d2b62015-02-18 11:12:02 -0800152 return StatusDataset.wireDecode(data.getContent(), RibEntry.class);
153 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800154
Andrew Brown211d2b62015-02-18 11:12:02 -0800155 /**
andrewsbrown39b0fc92015-05-11 13:44:38 -0700156 * Retrieve the list of strategy choice entries from the NFD; calls
157 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
158 * are dropped).
159 *
160 * @param forwarder only a localhost Face
161 * @return a list of strategy choice entries, i.e. routes, see
162 * http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice.
andrewsbrowndb628382015-05-28 10:47:30 -0700163 * @throws IOException if the network request failed
164 * @throws ManagementException if the NFD rejected the request
andrewsbrown39b0fc92015-05-11 13:44:38 -0700165 */
andrewsbrowndb628382015-05-28 10:47:30 -0700166 public static List<StrategyChoice> getStrategyList(Face forwarder) throws IOException, ManagementException {
andrewsbrown39b0fc92015-05-11 13:44:38 -0700167 Data data = retrieveDataSet(forwarder, new Name("/localhost/nfd/strategy-choice/list"));
168 return StatusDataset.wireDecode(data.getContent(), StrategyChoice.class);
169 }
170
171 /**
Andrew Brownc5dda702015-04-13 09:36:04 -0700172 * Retrieve the {@link KeyLocator} for an NFD.
173 *
174 * @param forwarder only a localhost {@link Face}
175 * @return the {@link KeyLocator} of the NFD's key
andrewsbrowndb628382015-05-28 10:47:30 -0700176 * @throws IOException if the network request failed
177 * @throws ManagementException if the NFD rejected the request or no
178 * KeyLocator was found
Andrew Brownc5dda702015-04-13 09:36:04 -0700179 */
180 public static KeyLocator getKeyLocator(Face forwarder) throws ManagementException, IOException {
181 Data data = retrieveStatus(forwarder);
182 if (!KeyLocator.canGetFromSignature(data.getSignature())) {
183 throw new ManagementException("No key locator available.");
184 }
185 return KeyLocator.getFromSignature(data.getSignature());
186 }
187
188 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800189 * Helper method to register a new face on the forwarder; as mentioned at
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700190 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>,
191 * this is more for debugging; use 'register' instead
Andrew Brown211d2b62015-02-18 11:12:02 -0800192 *
andrewsbrowndb628382015-05-28 10:47:30 -0700193 * @param forwarder only a localhost {@link Face}
194 * @param faceId the ID of the face to add, see
195 * {@link #createFace(net.named_data.jndn.Face, java.lang.String)} for
196 * creating this
197 * @param prefix the {@link Name} of the next-hop prefix
198 * @throws IOException if the network request failed
199 * @throws EncodingException if the NFD response could not be decoded
200 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800201 */
andrewsbrowndb628382015-05-28 10:47:30 -0700202 public static void addNextHop(Face forwarder, int faceId, Name prefix) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800203 // build command name
204 Name command = new Name("/localhost/nfd/fib/add-nexthop");
205 ControlParameters parameters = new ControlParameters();
206 parameters.setName(prefix);
207 parameters.setFaceId(faceId);
208 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800209
Andrew Brown211d2b62015-02-18 11:12:02 -0800210 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100211 sendCommand(forwarder, new Interest(command));
Andrew Brown211d2b62015-02-18 11:12:02 -0800212 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800213
Andrew Brown211d2b62015-02-18 11:12:02 -0800214 /**
215 * Create a new face on the given forwarder. Ensure the forwarding face is on
216 * the local machine (management requests are to /localhost/...) and that
217 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
218 *
andrewsbrowndb628382015-05-28 10:47:30 -0700219 * @param forwarder only a localhost {@link Face}
220 * @param uri a string like "tcp4://host.name.com" (see nfd-status channels
221 * for more protocol options)
222 * @return the newly created face ID
223 * @throws IOException if the network request failed
224 * @throws EncodingException if the NFD response could not be decoded
225 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800226 */
andrewsbrowndb628382015-05-28 10:47:30 -0700227 public static int createFace(Face forwarder, String uri) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800228 Name command = new Name("/localhost/nfd/faces/create");
229 ControlParameters parameters = new ControlParameters();
230 parameters.setUri(uri);
231 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800232
Andrew Brown211d2b62015-02-18 11:12:02 -0800233 // send the interest
234 ControlResponse response = sendCommand(forwarder, new Interest(command));
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800235
Andrew Brown211d2b62015-02-18 11:12:02 -0800236 // return
237 return response.getBody().get(0).getFaceId();
238 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800239
Andrew Brown211d2b62015-02-18 11:12:02 -0800240 /**
andrewsbrown43b96302015-03-17 21:51:43 +0100241 * Destroy a face on given forwarder. Ensure the forwarding face is on the
242 * local machine (management requests are to /localhost/...) and that command
243 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700244 *
andrewsbrowndb628382015-05-28 10:47:30 -0700245 * @param forwarder only a localhost {@link Face}
246 * @param faceId the ID of the face to destroy
247 * @throws IOException if the network request failed
248 * @throws EncodingException if the NFD response could not be decoded
249 * @throws ManagementException if the NFD rejected the request
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700250 */
andrewsbrowndb628382015-05-28 10:47:30 -0700251 public static void destroyFace(Face forwarder, int faceId) throws IOException, EncodingException, ManagementException {
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700252 Name command = new Name("/localhost/nfd/faces/destroy");
253 ControlParameters parameters = new ControlParameters();
254 parameters.setFaceId(faceId);
255 command.append(parameters.wireEncode());
256
257 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100258 sendCommand(forwarder, new Interest(command));
Alexander Afanasyev75d8dfc2015-03-13 16:41:01 -0700259 }
260
261 /**
andrewsbrowne8e8e852015-03-09 13:48:31 -0700262 * Enable a local control feature on the given forwarder. See
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700263 * <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature">http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Enable-a-LocalControlHeader-feature</a>
andrewsbrowne8e8e852015-03-09 13:48:31 -0700264 *
andrewsbrowndb628382015-05-28 10:47:30 -0700265 * @param forwarder only a localhost {@link Face}
266 * @param header the control feature to enable
267 * @throws IOException if the network request failed
268 * @throws EncodingException if the NFD response could not be decoded
269 * @throws ManagementException if the NFD rejected the request
andrewsbrowne8e8e852015-03-09 13:48:31 -0700270 */
andrewsbrowndb628382015-05-28 10:47:30 -0700271 public static void enableLocalControlHeader(Face forwarder, LocalControlHeader header) throws IOException, EncodingException, ManagementException {
andrewsbrowne8e8e852015-03-09 13:48:31 -0700272 // 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
andrewsbrown43b96302015-03-17 21:51:43 +0100279 sendCommand(forwarder, new Interest(command));
andrewsbrowne8e8e852015-03-09 13:48:31 -0700280 }
281
282 /**
283 * Disable a local control feature on the given forwarder. See
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700284 * <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature">http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Disable-a-LocalControlHeader-feature</a>
andrewsbrowne8e8e852015-03-09 13:48:31 -0700285 *
andrewsbrowndb628382015-05-28 10:47:30 -0700286 * @param forwarder only a localhost {@link Face}
287 * @param header the control feature to disable
288 * @throws IOException if the network request failed
289 * @throws EncodingException if the NFD response could not be decoded
290 * @throws ManagementException if the NFD rejected the request
andrewsbrowne8e8e852015-03-09 13:48:31 -0700291 */
andrewsbrowndb628382015-05-28 10:47:30 -0700292 public static void disableLocalControlHeader(Face forwarder, LocalControlHeader header) throws IOException, EncodingException, ManagementException {
andrewsbrowne8e8e852015-03-09 13:48:31 -0700293 // build command name
294 Name command = new Name("/localhost/nfd/faces/disable-local-control");
295 ControlParameters parameters = new ControlParameters();
296 parameters.setLocalControlFeature(header.getNumericValue());
297 command.append(parameters.wireEncode());
298
299 // send command and return
andrewsbrown43b96302015-03-17 21:51:43 +0100300 sendCommand(forwarder, new Interest(command));
andrewsbrowne8e8e852015-03-09 13:48:31 -0700301 }
302
303 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800304 * Register a route on the forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700305 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
306 * for command-line usage and
307 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
308 * for protocol documentation. Ensure the forwarding face is on the local
309 * machine (management requests are to /localhost/...) and that command
310 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
Andrew Brown211d2b62015-02-18 11:12:02 -0800311 *
andrewsbrowndb628382015-05-28 10:47:30 -0700312 * @param forwarder only a localhost {@link Face}
313 * @param controlParameters the {@link ControlParameters} command options
314 * @throws IOException if the network request failed
315 * @throws EncodingException if the NFD response could not be decoded
316 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800317 */
andrewsbrowndb628382015-05-28 10:47:30 -0700318 public static void register(Face forwarder, ControlParameters controlParameters) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800319 // build command name
320 Name command = new Name("/localhost/nfd/rib/register");
321 command.append(controlParameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800322
Andrew Brown211d2b62015-02-18 11:12:02 -0800323 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100324 sendCommand(forwarder, new Interest(command));
Andrew Brown211d2b62015-02-18 11:12:02 -0800325 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800326
Andrew Brown211d2b62015-02-18 11:12:02 -0800327 /**
328 * Register a route on a forwarder; this will create a new face on the
329 * forwarder to the given URI/route pair. See register(Face,
330 * ControlParameters) for more details documentation.
331 *
andrewsbrowndb628382015-05-28 10:47:30 -0700332 * @param forwarder only a localhost {@link Face}
333 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node
334 * @param route the {@link Name} prefix of the route
335 * @param cost the numeric cost of forwarding along the route
336 * @throws IOException if the network request failed
337 * @throws EncodingException if the NFD response could not be decoded
338 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800339 */
andrewsbrowndb628382015-05-28 10:47:30 -0700340 public static void register(Face forwarder, String uri, Name route, int cost) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800341 // create the new face
342 int faceId = createFace(forwarder, uri);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800343
Andrew Brown211d2b62015-02-18 11:12:02 -0800344 // run base method
andrewsbrown43b96302015-03-17 21:51:43 +0100345 register(forwarder, faceId, route, cost);
Andrew Brown211d2b62015-02-18 11:12:02 -0800346 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800347
Andrew Brown211d2b62015-02-18 11:12:02 -0800348 /**
349 * Register a route on a forwarder; this will not create a new face since it
350 * is provided a faceId. See register(Face, ControlParameters) for full
351 * documentation
352 *
andrewsbrowndb628382015-05-28 10:47:30 -0700353 * @param forwarder only a localhost {@link Face}
354 * @param faceId the ID of the {@link Face} to assign to the route
355 * @param route the {@link Name} prefix of the route
356 * @param cost the numeric cost of forwarding along the route
357 * @throws IOException if the network request failed
358 * @throws EncodingException if the NFD response could not be decoded
359 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800360 */
andrewsbrowndb628382015-05-28 10:47:30 -0700361 public static void register(Face forwarder, int faceId, Name route, int cost) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800362 // build command name
363 ControlParameters parameters = new ControlParameters();
364 parameters.setName(route);
365 parameters.setFaceId(faceId);
366 parameters.setCost(cost);
367 ForwardingFlags flags = new ForwardingFlags();
368 flags.setCapture(true);
369 flags.setChildInherit(true);
370 parameters.setForwardingFlags(flags);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800371
Andrew Brown211d2b62015-02-18 11:12:02 -0800372 // run base method
andrewsbrown43b96302015-03-17 21:51:43 +0100373 register(forwarder, parameters);
Andrew Brown211d2b62015-02-18 11:12:02 -0800374 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800375
Andrew Brown211d2b62015-02-18 11:12:02 -0800376 /**
Andrew Brown63bed362015-02-18 11:28:50 -0800377 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700378 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
379 * for command-line usage and
380 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
381 * for protocol documentation. Ensure the forwarding face is on the local
382 * machine (management requests are to /localhost/...) and that command
383 * signing has been set up (e.g. forwarder.setCommandSigningInfo()
Andrew Brown63bed362015-02-18 11:28:50 -0800384 *
andrewsbrowndb628382015-05-28 10:47:30 -0700385 * @param forwarder only a localhost {@link Face}
386 * @param controlParameters the {@link ControlParameters} command options
387 * @throws IOException if the network request failed
388 * @throws EncodingException if the NFD response could not be decoded
389 * @throws ManagementException if the NFD rejected the request
Andrew Brown63bed362015-02-18 11:28:50 -0800390 */
andrewsbrowndb628382015-05-28 10:47:30 -0700391 public static void unregister(Face forwarder, ControlParameters controlParameters) throws IOException, EncodingException, ManagementException {
Andrew Brown63bed362015-02-18 11:28:50 -0800392 // build command name
393 Name command = new Name("/localhost/nfd/rib/unregister");
394 command.append(controlParameters.wireEncode());
395
396 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100397 sendCommand(forwarder, new Interest(command));
Andrew Brown63bed362015-02-18 11:28:50 -0800398 }
399
400 /**
Andrew Brown07466442015-02-24 09:07:02 -0800401 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700402 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
403 * for command-line usage and
404 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
405 * for protocol documentation. Ensure the forwarding face is on the local
406 * machine (management requests are to /localhost/...) and that command
407 * signing has been set up (e.g. forwarder.setCommandSigningInfo()
Andrew Brown07466442015-02-24 09:07:02 -0800408 *
andrewsbrowndb628382015-05-28 10:47:30 -0700409 * @param forwarder only a localhost {@link Face}
410 * @param route the {@link Name} prefix of the route
411 * @throws IOException if the network request failed
412 * @throws EncodingException if the NFD response could not be decoded
413 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800414 */
andrewsbrowndb628382015-05-28 10:47:30 -0700415 public static void unregister(Face forwarder, Name route) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800416 // build command name
417 ControlParameters controlParameters = new ControlParameters();
418 controlParameters.setName(route);
419
420 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100421 unregister(forwarder, controlParameters);
Andrew Brown07466442015-02-24 09:07:02 -0800422 }
423
424 /**
425 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700426 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
427 * for command-line usage and
428 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
429 * for protocol documentation. Ensure the forwarding face is on the local
430 * machine (management requests are to /localhost/...) and that command
431 * signing has been set up (e.g. forwarder.setCommandSigningInfo()
Andrew Brown07466442015-02-24 09:07:02 -0800432 *
andrewsbrowndb628382015-05-28 10:47:30 -0700433 * @param forwarder only a localhost {@link Face}
434 * @param route the {@link Name} prefix of the route
435 * @param faceId the specific ID of the face to remove (more than one face can
436 * be registered to a route)
437 * @throws IOException if the network request failed
438 * @throws EncodingException if the NFD response could not be decoded
439 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800440 */
andrewsbrowndb628382015-05-28 10:47:30 -0700441 public static void unregister(Face forwarder, Name route, int faceId) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800442 // build command name
443 ControlParameters controlParameters = new ControlParameters();
444 controlParameters.setName(route);
445 controlParameters.setFaceId(faceId);
446
447 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100448 unregister(forwarder, controlParameters);
Andrew Brown07466442015-02-24 09:07:02 -0800449 }
450
451 /**
452 * Unregister a route on a forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700453 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
454 * for command-line usage and
455 * <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">http://redmine.named-data.net/projects/nfd/wiki/RibMgmt</a>
456 * for protocol documentation. Ensure the forwarding face is on the local
457 * machine (management requests are to /localhost/...) and that command
458 * signing has been set up (e.g. forwarder.setCommandSigningInfo()
Andrew Brown07466442015-02-24 09:07:02 -0800459 *
andrewsbrowndb628382015-05-28 10:47:30 -0700460 * @param forwarder only a localhost {@link Face}
461 * @param route the {@link Name} prefix of the route
462 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node (more
463 * than one face can be registered to a route)
464 * @throws IOException if the network request failed
465 * @throws EncodingException if the NFD response could not be decoded
466 * @throws ManagementException if the NFD rejected the request
Andrew Brown07466442015-02-24 09:07:02 -0800467 */
andrewsbrowndb628382015-05-28 10:47:30 -0700468 public static void unregister(Face forwarder, Name route, String uri) throws IOException, EncodingException, ManagementException {
Andrew Brown07466442015-02-24 09:07:02 -0800469 int faceId = -1;
andrewsbrown4c21ea22015-03-09 12:05:03 -0700470 for (FaceStatus face : getFaceList(forwarder)) {
471 if (face.getUri().matches(uri)) {
Andrew Brown07466442015-02-24 09:07:02 -0800472 faceId = face.getFaceId();
473 break;
474 }
475 }
andrewsbrown4c21ea22015-03-09 12:05:03 -0700476
477 if (faceId == -1) {
andrewsbrown43b96302015-03-17 21:51:43 +0100478 throw new ManagementException("Face not found: " + uri);
Andrew Brown07466442015-02-24 09:07:02 -0800479 }
480
481 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100482 unregister(forwarder, route, faceId);
Andrew Brown07466442015-02-24 09:07:02 -0800483 }
484
485 /**
Andrew Brown211d2b62015-02-18 11:12:02 -0800486 * Set a strategy on the forwarder; see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700487 * <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">http://named-data.net/doc/NFD/current/manpages/nfdc.html</a>
488 * for command-line usage and
489 * <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice</a>
Andrew Brown211d2b62015-02-18 11:12:02 -0800490 * for protocol documentation. Ensure the forwarding face is on the local
491 * machine (management requests are to /localhost/...) and that command
492 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
493 *
andrewsbrowndb628382015-05-28 10:47:30 -0700494 * @param forwarder only a localhost {@link Face}
andrewsbrowncad04eb2015-05-11 13:16:24 -0700495 * @param prefix the {@link Name} prefix
andrewsbrown39b0fc92015-05-11 13:44:38 -0700496 * @param strategy the {@link Name} of the strategy to set, e.g.
497 * /localhost/nfd/strategy/broadcast
andrewsbrowndb628382015-05-28 10:47:30 -0700498 * @throws IOException if the network request failed
499 * @throws EncodingException if the NFD response could not be decoded
500 * @throws ManagementException if the NFD rejected the request
Andrew Brown211d2b62015-02-18 11:12:02 -0800501 */
andrewsbrowndb628382015-05-28 10:47:30 -0700502 public static void setStrategy(Face forwarder, Name prefix, Name strategy) throws IOException, EncodingException, ManagementException {
Andrew Brown211d2b62015-02-18 11:12:02 -0800503 // build command name
504 Name command = new Name("/localhost/nfd/strategy-choice/set");
505 ControlParameters parameters = new ControlParameters();
506 parameters.setName(prefix);
507 parameters.setStrategy(strategy);
508 command.append(parameters.wireEncode());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800509
Andrew Brown211d2b62015-02-18 11:12:02 -0800510 // send the interest
andrewsbrown43b96302015-03-17 21:51:43 +0100511 sendCommand(forwarder, new Interest(command));
512 }
513
514 /**
andrewsbrowncad04eb2015-05-11 13:16:24 -0700515 * Set a strategy on the forwarder; see
516 * {@link #setStrategy(net.named_data.jndn.Face, net.named_data.jndn.Name, net.named_data.jndn.Name)}
517 * for more information. Ensure the forwarding face is on the local machine
518 * (management requests are to /localhost/...) and that command signing has
519 * been set up (e.g. forwarder.setCommandSigningInfo()).
520 *
521 * @param forwarder only a localhost {@link Face}
522 * @param prefix the {@link Name} prefix
andrewsbrowndb628382015-05-28 10:47:30 -0700523 * @throws IOException if the network request failed
524 * @throws EncodingException if the NFD response could not be decoded
525 * @throws ManagementException if the NFD rejected the request
andrewsbrowncad04eb2015-05-11 13:16:24 -0700526 */
andrewsbrowndb628382015-05-28 10:47:30 -0700527 public static void unsetStrategy(Face forwarder, Name prefix) throws IOException, EncodingException, ManagementException {
andrewsbrowncad04eb2015-05-11 13:16:24 -0700528 // build command name
Andrew Brown37cec242015-05-11 14:24:13 -0700529 Name command = new Name("/localhost/nfd/strategy-choice/unset");
andrewsbrowncad04eb2015-05-11 13:16:24 -0700530 ControlParameters parameters = new ControlParameters();
531 parameters.setName(prefix);
532 command.append(parameters.wireEncode());
533
534 // send the interest
535 sendCommand(forwarder, new Interest(command));
536 }
537
538 /**
Andrew Brownc5dda702015-04-13 09:36:04 -0700539 * Build an interest to retrieve the NFD status.
540 *
541 * @param forwarder only a localhost {@link Face}
542 * @return the status {@link Data} packet
543 * @throws IOException if the retrieval fails
544 */
545 private static Data retrieveStatus(Face forwarder) throws IOException {
546 Interest interest = new Interest(new Name("/localhost/nfd/status"));
547 interest.setMustBeFresh(true);
548 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
549 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
550 Data data = SimpleClient.getDefault().getSync(forwarder, interest);
551 return data;
552 }
553
554 /**
andrewsbrown43b96302015-03-17 21:51:43 +0100555 * Build an interest to retrieve a segmented data set from the NFD; for
556 * details on the DataSet, see
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700557 * <a href="http://redmine.named-data.net/projects/nfd/wiki/StatusDataset">http://redmine.named-data.net/projects/nfd/wiki/StatusDataset</a>
andrewsbrown43b96302015-03-17 21:51:43 +0100558 *
Andrew Brownc5dda702015-04-13 09:36:04 -0700559 * @param forwarder the {@link Face} to an NFD
560 * @param datasetName the {@link Name} of the dataset to retrieve
561 * @return the re-assembled {@link Data} packet
562 * @throws IOException if the request fails
563 * @throws ManagementException if the returned TLV is not the expected type
andrewsbrown43b96302015-03-17 21:51:43 +0100564 */
565 public static Data retrieveDataSet(Face forwarder, Name datasetName) throws IOException, ManagementException {
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700566 // build management Interest packet; see <a href="http://redmine.named-data.net/projects/nfd/wiki/StatusDataset">http://redmine.named-data.net/projects/nfd/wiki/StatusDataset</a>
Andrew Brown0e904e12015-03-17 14:10:29 -0700567 Interest interest = new Interest(datasetName);
andrewsbrown43b96302015-03-17 21:51:43 +0100568 interest.setMustBeFresh(true);
569 interest.setChildSelector(Interest.CHILD_SELECTOR_RIGHT);
570 interest.setInterestLifetimeMilliseconds(DEFAULT_TIMEOUT);
571
572 // send packet
573 Data data = SegmentedClient.getDefault().getSync(forwarder, interest);
574
575 // check for failed request
576 if (data.getContent().buf().get(0) == ControlResponse.TLV_CONTROL_RESPONSE) {
577 throw ManagementException.fromResponse(data.getContent());
578 }
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700579
andrewsbrown43b96302015-03-17 21:51:43 +0100580 return data;
Andrew Brown211d2b62015-02-18 11:12:02 -0800581 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800582
Andrew Brown211d2b62015-02-18 11:12:02 -0800583 /**
584 * Send an interest as a command to the forwarder; this method will convert
585 * the interest to a command interest and block until a response is received
586 * from the forwarder. Ensure the forwarding face is on the local machine
587 * (management requests are to /localhost/...) and that command signing has
588 * been set up (e.g. forwarder.setCommandSigningInfo()).
589 *
andrewsbrown8a32f302015-03-24 08:42:46 -0700590 * @param forwarder only a localhost Face, command signing info must be set
Andrew Brown211d2b62015-02-18 11:12:02 -0800591 * @param interest As described at
andrewsbrown9a6d7ba2015-03-24 09:53:29 -0700592 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ControlCommand,">http://redmine.named-data.net/projects/nfd/wiki/ControlCommand,</a>
593 * the requested interest must have encoded ControlParameters appended to the
Andrew Brown211d2b62015-02-18 11:12:02 -0800594 * interest name
Andrew Brownc5dda702015-04-13 09:36:04 -0700595 * @return a {@link ControlResponse}
Andrew Brown211d2b62015-02-18 11:12:02 -0800596 * @throws java.io.IOException
597 * @throws net.named_data.jndn.encoding.EncodingException
andrewsbrown43b96302015-03-17 21:51:43 +0100598 * @throws com.intel.jndn.management.ManagementException
Andrew Brown211d2b62015-02-18 11:12:02 -0800599 */
andrewsbrown43b96302015-03-17 21:51:43 +0100600 public static ControlResponse sendCommand(Face forwarder, Interest interest) throws IOException, EncodingException, ManagementException {
601 // forwarder must have command signing info set
602 try {
603 forwarder.makeCommandInterest(interest);
604 } catch (SecurityException e) {
605 throw new IllegalArgumentException("Failed to make command interest; ensure command signing info is set on the face.", e);
606 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800607
Andrew Brown211d2b62015-02-18 11:12:02 -0800608 // send command packet
andrewsbrown43b96302015-03-17 21:51:43 +0100609 Data data = SimpleClient.getDefault().getSync(forwarder, interest);
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800610
andrewsbrown43b96302015-03-17 21:51:43 +0100611 // decode response
Andrew Brown211d2b62015-02-18 11:12:02 -0800612 ControlResponse response = new ControlResponse();
613 response.wireDecode(data.getContent().buf());
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800614
andrewsbrown43b96302015-03-17 21:51:43 +0100615 // check response for success
616 if (response.getStatusCode() != OK_STATUS) {
617 throw ManagementException.fromResponse(response);
Andrew Brown211d2b62015-02-18 11:12:02 -0800618 }
andrewsbrown43b96302015-03-17 21:51:43 +0100619
620 return response;
Andrew Brown211d2b62015-02-18 11:12:02 -0800621 }
Andrew Brown2f1fdbf2015-01-21 10:52:29 -0800622}