blob: a48e88f7204932e83aff36d9766dfca7d7e1fe8d [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 Afanasyev7ac3e392016-02-19 23:21:01 -080020import com.intel.jndn.management.types.ChannelStatus;
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080021import com.intel.jndn.management.types.FaceStatus;
22import com.intel.jndn.management.types.FibEntry;
23import com.intel.jndn.management.types.ForwarderStatus;
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080024import com.intel.jndn.management.types.RibEntry;
25import com.intel.jndn.management.types.StrategyChoice;
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -080026import net.named_data.jndn.ControlParameters;
27import net.named_data.jndn.ControlResponse;
28import net.named_data.jndn.Data;
29import net.named_data.jndn.Face;
30import net.named_data.jndn.ForwardingFlags;
31import net.named_data.jndn.Interest;
32import net.named_data.jndn.KeyLocator;
33import net.named_data.jndn.Name;
34import net.named_data.jndn.encoding.EncodingException;
35import net.named_data.jndn.security.SecurityException;
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080036
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080037import java.io.IOException;
38import java.util.List;
39
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080040/**
41 * Helper class for interacting with an NDN forwarder daemon; see
42 * <a href="http://redmine.named-data.net/projects/nfd/wiki/Management">NFD Management</a>
43 * for explanations of the various protocols used.
44 *
45 * @author Andrew Brown <andrew.brown@intel.com>
46 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080047public final class Nfdc {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080048 private static final int OK_STATUS = 200;
49
50 /////////////////////////////////////////////////////////////////////////////
51
52 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080053 * Prevent creation of Nfdc instances.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080054 */
55 private Nfdc() {
56 }
57
58 /**
59 * Retrieve the status of the given forwarder; calls /localhost/nfd/status/general
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080060 * which requires a local Face (all non-local packets are dropped).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080061 *
62 * @param face only a localhost Face
63 * @return the forwarder status object
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080064 * @throws ManagementException if the network request failed or the returned status could not be decoded
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080065 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus">ForwarderStatus</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080066 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080067 public static ForwarderStatus getForwarderStatus(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080068 try {
69 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/status/general"));
70 return new ForwarderStatus(StatusDatasetHelper.combine(segments));
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080071 } catch (IOException | EncodingException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080072 throw new ManagementException(e.getMessage(), e);
73 }
74 }
75
76 /**
77 * Retrieve a list of faces and their status from the given forwarder; calls
78 * /localhost/nfd/faces/list which requires a local Face (all non-local
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080079 * packets are dropped).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080080 *
81 * @param face only a localhost Face
82 * @return a list of face status objects
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080083 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080084 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">FaceManagement</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080085 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -080086 public static List<FaceStatus> getFaceList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -080087 try {
88 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/faces/list"));
89 return StatusDatasetHelper.wireDecode(segments, FaceStatus.class);
90 } catch (IOException e) {
91 throw new ManagementException(e.getMessage(), e);
92 }
93 }
94
95 /**
96 * Retrieve a list of FIB entries and their NextHopRecords from the given
97 * forwarder; calls /localhost/nfd/fib/list which requires a local Face (all
98 * non-local packets are dropped).
99 *
100 * @param face only a localhost Face
101 * @return a list of FIB entries
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800102 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800103 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FibMgmt#FIB-Dataset">FIB Dataset</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800104 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800105 public static List<FibEntry> getFibList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800106 try {
107 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/fib/list"));
108 return StatusDatasetHelper.wireDecode(segments, FibEntry.class);
109 } catch (IOException e) {
110 throw new ManagementException(e.getMessage(), e);
111 }
112 }
113
114 /**
115 * Retrieve a list of routing entries from the RIB; calls
116 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
117 * are dropped).
118 *
119 * @param face only a localhost Face
120 * @return a list of RIB entries, i.e. routes
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800121 * @throws ManagementException if the network request failed or if the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800122 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt#RIB-Dataset">RIB Dataset</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800123 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800124 public static List<RibEntry> getRouteList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800125 try {
126 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/rib/list"));
127 return StatusDatasetHelper.wireDecode(segments, RibEntry.class);
Andrew Brown862fe422016-10-07 10:02:26 -0700128 } catch (IOException e) {
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 /**
Alexander Afanasyev7ac3e392016-02-19 23:21:01 -0800154 * Retrieve the list of channel status entries from the NFD; calls
155 * /localhost/nfd/faces/channels which requires a local Face (all non-local packets
156 * are dropped).
157 *
158 * @param face only a localhost Face
159 * @return a list of channel status entries
160 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
161 * the NFD rejected the request
162 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Channel-Dataset">Face Management</a>
163 */
164 public static List<ChannelStatus> getChannelStatusList(final Face face) throws ManagementException {
165 try {
166 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/faces/channels"));
167 return StatusDatasetHelper.wireDecode(segments, ChannelStatus.class);
168 } catch (IOException e) {
169 throw new ManagementException(e.getMessage(), e);
170 }
171 }
172 /**
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800173 * Retrieve the {@link KeyLocator} for an NFD.
174 *
175 * @param face only a localhost {@link Face}
176 * @return the {@link KeyLocator} of the NFD's key
177 * @throws ManagementException if the network request failed, if the NFD rejected the request, or no
178 * KeyLocator was found
179 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800180 public static KeyLocator getKeyLocator(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800181 try {
182 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/status/general"));
183 if (segments.isEmpty() || !KeyLocator.canGetFromSignature(segments.get(0).getSignature())) {
184 throw new ManagementException("No key locator available.");
185 }
186 return KeyLocator.getFromSignature(segments.get(0).getSignature());
187 } catch (IOException e) {
188 throw new ManagementException(e.getMessage(), e);
189 }
190 }
191
192 /**
193 * Create a new face on the given forwarder. Ensure the forwarding face is on
194 * the local machine (management requests are to /localhost/...) and that
195 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
196 *
197 * @param face only a localhost {@link Face}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800198 * @param uri a string like "tcp4://host.name.com" (see nfd-status channels
199 * for more protocol options)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800200 * @return the newly created face ID
201 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
202 * the NFD rejected the request
203 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800204 public static int createFace(final Face face, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800205 Name command = new Name("/localhost/nfd/faces/create");
206 ControlParameters parameters = new ControlParameters();
207 parameters.setUri(uri);
208 command.append(parameters.wireEncode());
209
210 try {
211 // send the interest
212 ControlResponse response = sendCommand(face, command);
213
214 // return
Alexander Afanasyev499aced2016-02-17 19:32:37 -0800215 return response.getBodyAsControlParameters().getFaceId();
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800216 } catch (IOException | EncodingException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800217 throw new ManagementException(e.getMessage(), e);
218 }
219 }
220
221 /**
222 * Destroy a face on given forwarder. Ensure the forwarding face is on the
223 * local machine (management requests are to /localhost/...) and that command
224 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
225 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800226 * @param face only a localhost {@link Face}
227 * @param faceId the ID of the face to destroy
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800228 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
229 * the NFD rejected the request
230 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800231 public static void destroyFace(final Face face, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800232 Name command = new Name("/localhost/nfd/faces/destroy");
233 ControlParameters parameters = new ControlParameters();
234 parameters.setFaceId(faceId);
235 command.append(parameters.wireEncode());
236
237 try {
238 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800239 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800240 throw new ManagementException(e.getMessage(), e);
241 }
242 }
243
244 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800245 * Enable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800246 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800247 * @param face only a localhost {@link Face}
248 * @param header the control feature to enable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800249 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
250 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800251 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800252 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800253 public static void enableLocalControlHeader(final Face face, final LocalControlHeader header) throws
254 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800255 // build command name
256 Name command = new Name("/localhost/nfd/faces/enable-local-control");
257 ControlParameters parameters = new ControlParameters();
258 parameters.setLocalControlFeature(header.toInteger());
259 command.append(parameters.wireEncode());
260
261 try {
262 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800263 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800264 throw new ManagementException(e.getMessage(), e);
265 }
266 }
267
268 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800269 * Disable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800270 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800271 * @param face only a localhost {@link Face}
272 * @param header the control feature to disable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800273 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
274 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800275 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800276 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800277 public static void disableLocalControlHeader(final Face face, final LocalControlHeader header) throws
278 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800279 // build command name
280 Name command = new Name("/localhost/nfd/faces/disable-local-control");
281 ControlParameters parameters = new ControlParameters();
282 parameters.setLocalControlFeature(header.toInteger());
283 command.append(parameters.wireEncode());
284
285 try {
286 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800287 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800288 throw new ManagementException(e.getMessage(), e);
289 }
290 }
291
292 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800293 * Register a route on the forwarder.
294 * <p/>
295 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800296 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
297 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800298 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800299 * @param controlParameters the {@link ControlParameters} command options
300 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
301 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800302 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
303 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800304 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800305 public static void register(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800306 // build command name
307 Name command = new Name("/localhost/nfd/rib/register");
308 command.append(controlParameters.wireEncode());
309
310 try {
311 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800312 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800313 throw new ManagementException(e.getMessage(), e);
314 }
315 }
316
317 /**
318 * Register a route on a forwarder; this will create a new face on the
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800319 * forwarder towards the face (e.g., self registration).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800320 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800321 * @param face only a localhost {@link Face}
322 * @param route the {@link Name} prefix of the route
323 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800324 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
325 * the NFD rejected the request
326 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800327 public static void register(final Face face, final Name route, final int cost) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800328 ForwardingFlags flags = new ForwardingFlags();
329 flags.setCapture(false);
330 flags.setChildInherit(true);
331
332 register(face, new ControlParameters()
333 .setName(route)
334 .setCost(cost)
335 .setOrigin(RouteOrigin.APP.toInteger())
336 .setForwardingFlags(flags));
337 }
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800338
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800339 /**
340 * Register a route on a forwarder; this will create a new face on the
341 * forwarder to the given URI/route pair. See register(Face,
342 * ControlParameters) for more detailed documentation.
343 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800344 * @param face only a localhost {@link Face}
345 * @param uri the URI (e.g. "tcp4://10.10.2.2:6363") of the remote node; note
346 * that this must be one of the canonical forms described in the wiki
347 * (http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#TCP) for NFD to
348 * accept the registration--otherwise you will see 400 errors
349 * @param route the {@link Name} prefix of the route
350 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800351 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
352 * the NFD rejected the request
353 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800354 public static void register(final Face face, final String uri, final Name route, final int cost) throws
355 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800356 // create the new face
357 int faceId = createFace(face, uri);
358
359 // run base method
360 register(face, faceId, route, cost);
361 }
362
363 /**
364 * Register a route on a forwarder; this will not create a new face since it
365 * is provided a faceId. See register(Face, ControlParameters) for full
366 * documentation.
367 *
368 * @param forwarder only a localhost {@link Face}
369 * @param faceId the ID of the {@link Face} to assign to the route
370 * @param route the {@link Name} prefix of the route
371 * @param cost the numeric cost of forwarding along the route
372 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
373 * the NFD rejected the request
374 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800375 public static void register(final Face forwarder, final int faceId, final Name route, final int cost) throws
376 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800377 // build command name
378 ControlParameters parameters = new ControlParameters();
379 parameters.setName(route);
380 parameters.setFaceId(faceId);
381 parameters.setCost(cost);
382 parameters.setOrigin(RouteOrigin.STATIC.toInteger());
383 ForwardingFlags flags = new ForwardingFlags();
384 flags.setCapture(false);
385 flags.setChildInherit(true);
386 parameters.setForwardingFlags(flags);
387
388 // run base method
389 register(forwarder, parameters);
390 }
391
392 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800393 * Unregister a route on a forwarder
394 * <p/>
395 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
396 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800397 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800398 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800399 * @param controlParameters the {@link ControlParameters} command options
400 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
401 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800402 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
403 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800404 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800405 public static void unregister(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800406 // build command name
407 Name command = new Name("/localhost/nfd/rib/unregister");
408 command.append(controlParameters.wireEncode());
409
410 try {
411 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800412 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800413 throw new ManagementException(e.getMessage(), e);
414 }
415 }
416
417 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800418 * Unregister a route on a forwarder.
419 * <p/>
420 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800421 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
422 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800423 * @param face only a localhost {@link Face}
424 * @param route the {@link Name} prefix of the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800425 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
426 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800427 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
428 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800429 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800430 public static void unregister(final Face face, final Name route) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800431 // build command name
432 ControlParameters controlParameters = new ControlParameters();
433 controlParameters.setName(route);
434
435 // send the interest
436 unregister(face, controlParameters);
437 }
438
439 /**
440 * Unregister a route on a forwarder; see
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800441 * <p/>
442 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800443 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
444 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800445 * @param face only a localhost {@link Face}
446 * @param route the {@link Name} prefix of the route
447 * @param faceId the specific ID of the face to remove (more than one face can
448 * be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800449 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
450 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800451 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
452 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800453 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800454 public static void unregister(final Face face, final Name route, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800455 // build command name
456 ControlParameters controlParameters = new ControlParameters();
457 controlParameters.setName(route);
458 controlParameters.setFaceId(faceId);
459
460 // send the interest
461 unregister(face, controlParameters);
462 }
463
464 /**
465 * Unregister a route on a forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800466 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800467 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
468 * signing has been set up using forwarder.setCommandSigningInfo().
469 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800470 * @param face only a localhost {@link Face}
471 * @param route the {@link Name} prefix of the route
472 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node (more
473 * than one face can be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800474 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
475 * the NFD rejected the request
476 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
477 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RibMgmt</a>
478 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800479 public static void unregister(final Face face, final Name route, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800480 int faceId = -1;
481 for (FaceStatus faceStatus : getFaceList(face)) {
482 if (faceStatus.getRemoteUri().matches(uri)) {
483 faceId = faceStatus.getFaceId();
484 break;
485 }
486 }
487
488 if (faceId == -1) {
489 throw new ManagementException("Face not found: " + uri);
490 }
491
492 // send the interest
493 unregister(face, route, faceId);
494 }
495
496 /**
497 * Set a strategy on the forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800498 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800499 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
500 * signing has been set up using forwarder.setCommandSigningInfo().
501 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800502 * @param face only a localhost {@link Face}
503 * @param prefix the {@link Name} prefix
504 * @param strategy the {@link Name} of the strategy to set, e.g.
505 * /localhost/nfd/strategy/broadcast
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800506 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
507 * the NFD rejected the request
508 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
509 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">StrategyChoice</a>
510 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800511 public static void setStrategy(final Face face, final Name prefix, final Name strategy) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800512 // build command name
513 Name command = new Name("/localhost/nfd/strategy-choice/set");
514 ControlParameters parameters = new ControlParameters();
515 parameters.setName(prefix);
516 parameters.setStrategy(strategy);
517 command.append(parameters.wireEncode());
518
519 try {
520 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800521 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800522 throw new ManagementException(e.getMessage(), e);
523 }
524 }
525
526 /**
527 * Set a strategy on the forwarder; see
528 * {@link #setStrategy(net.named_data.jndn.Face, net.named_data.jndn.Name, net.named_data.jndn.Name)}
529 * for more information. Ensure the forwarding face is on the local machine
530 * (management requests are to /localhost/...) and that command signing has
531 * been set up (e.g. forwarder.setCommandSigningInfo()).
532 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800533 * @param face only a localhost {@link Face}
534 * @param prefix the {@link Name} prefix
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800535 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
536 * the NFD rejected the request
537 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800538 public static void unsetStrategy(final Face face, final Name prefix) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800539 // build command name
540 Name command = new Name("/localhost/nfd/strategy-choice/unset");
541 ControlParameters parameters = new ControlParameters();
542 parameters.setName(prefix);
543 command.append(parameters.wireEncode());
544
545 try {
546 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800547 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800548 throw new ManagementException(e.getMessage(), e);
549 }
550 }
551
552 /**
553 * Send an interest as a command to the forwarder; this method will convert
554 * the interest to a command interest and block until a response is received
555 * from the forwarder. Ensure the forwarding face is on the local machine
556 * (management requests are to /localhost/...) and that command signing has
557 * been set up (e.g. forwarder.setCommandSigningInfo()).
558 *
559 * @param face only a localhost Face, command signing info must be set
560 * @param name As described at
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800561 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ControlCommand">ControlCommand</a>,
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800562 * the requested interest must have encoded ControlParameters appended to the
563 * interest name
564 * @return a {@link ControlResponse}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800565 * @throws IOException if the network request failed
566 * @throws EncodingException if the NFD response could not be decoded
567 * @throws ManagementException if the NFD rejected the request
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800568 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800569 private static ControlResponse sendCommand(final Face face, final Name name) throws IOException, EncodingException,
570 ManagementException {
Andrew Brown5a8b7c42016-10-06 09:54:36 -0700571 if (face == null) {
572 throw new IllegalArgumentException("Face parameter is null.");
573 }
574
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800575 Interest interest = new Interest(name);
576
577 // forwarder must have command signing info set
578 try {
579 face.makeCommandInterest(interest);
Andrew Brown5a8b7c42016-10-06 09:54:36 -0700580 } catch (SecurityException e) {
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800581 throw new IllegalArgumentException("Failed to make command interest; ensure command signing info is set on the " +
582 "face.", e);
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800583 }
584
585 // send command packet
586 Data data = FetchHelper.getData(face, interest.getName());
587
588 // decode response
589 ControlResponse response = new ControlResponse();
590 response.wireDecode(data.getContent().buf());
591
592 // check response for success
593 if (response.getStatusCode() != OK_STATUS) {
594 throw ManagementException.fromResponse(response);
595 }
596
597 return response;
598 }
599}