blob: f8a780d60e977707d635463951639a234a848987 [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);
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -0800128 } catch (ArrayIndexOutOfBoundsException | IOException e) {
129 // TODO: remove ArrayIndexOutOfBoundsException after fixing bug in MockFace
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800130 throw new ManagementException(e.getMessage(), e);
131 }
132 }
133
134 /**
135 * Retrieve the list of strategy choice entries from the NFD; calls
136 * /localhost/nfd/rib/list which requires a local Face (all non-local packets
137 * are dropped).
138 *
139 * @param face only a localhost Face
140 * @return a list of strategy choice entries, i.e. routes
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800141 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
142 * the NFD rejected the request
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800143 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">StrategyChoice</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800144 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800145 public static List<StrategyChoice> getStrategyList(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800146 try {
147 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/strategy-choice/list"));
148 return StatusDatasetHelper.wireDecode(segments, StrategyChoice.class);
149 } catch (IOException e) {
150 throw new ManagementException(e.getMessage(), e);
151 }
152 }
153
154 /**
Alexander Afanasyev7ac3e392016-02-19 23:21:01 -0800155 * Retrieve the list of channel status entries from the NFD; calls
156 * /localhost/nfd/faces/channels which requires a local Face (all non-local packets
157 * are dropped).
158 *
159 * @param face only a localhost Face
160 * @return a list of channel status entries
161 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
162 * the NFD rejected the request
163 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Channel-Dataset">Face Management</a>
164 */
165 public static List<ChannelStatus> getChannelStatusList(final Face face) throws ManagementException {
166 try {
167 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/faces/channels"));
168 return StatusDatasetHelper.wireDecode(segments, ChannelStatus.class);
169 } catch (IOException e) {
170 throw new ManagementException(e.getMessage(), e);
171 }
172 }
173 /**
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800174 * Retrieve the {@link KeyLocator} for an NFD.
175 *
176 * @param face only a localhost {@link Face}
177 * @return the {@link KeyLocator} of the NFD's key
178 * @throws ManagementException if the network request failed, if the NFD rejected the request, or no
179 * KeyLocator was found
180 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800181 public static KeyLocator getKeyLocator(final Face face) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800182 try {
183 List<Data> segments = FetchHelper.getSegmentedData(face, new Name("/localhost/nfd/status/general"));
184 if (segments.isEmpty() || !KeyLocator.canGetFromSignature(segments.get(0).getSignature())) {
185 throw new ManagementException("No key locator available.");
186 }
187 return KeyLocator.getFromSignature(segments.get(0).getSignature());
188 } catch (IOException e) {
189 throw new ManagementException(e.getMessage(), e);
190 }
191 }
192
193 /**
194 * Create a new face on the given forwarder. Ensure the forwarding face is on
195 * the local machine (management requests are to /localhost/...) and that
196 * command signing has been set up (e.g. forwarder.setCommandSigningInfo()).
197 *
198 * @param face only a localhost {@link Face}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800199 * @param uri a string like "tcp4://host.name.com" (see nfd-status channels
200 * for more protocol options)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800201 * @return the newly created face ID
202 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
203 * the NFD rejected the request
204 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800205 public static int createFace(final Face face, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800206 Name command = new Name("/localhost/nfd/faces/create");
207 ControlParameters parameters = new ControlParameters();
208 parameters.setUri(uri);
209 command.append(parameters.wireEncode());
210
211 try {
212 // send the interest
213 ControlResponse response = sendCommand(face, command);
214
215 // return
Alexander Afanasyev499aced2016-02-17 19:32:37 -0800216 return response.getBodyAsControlParameters().getFaceId();
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800217 } catch (IOException | EncodingException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800218 throw new ManagementException(e.getMessage(), e);
219 }
220 }
221
222 /**
223 * Destroy a face on given forwarder. Ensure the forwarding face is on the
224 * local machine (management requests are to /localhost/...) and that command
225 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
226 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800227 * @param face only a localhost {@link Face}
228 * @param faceId the ID of the face to destroy
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800229 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
230 * the NFD rejected the request
231 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800232 public static void destroyFace(final Face face, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800233 Name command = new Name("/localhost/nfd/faces/destroy");
234 ControlParameters parameters = new ControlParameters();
235 parameters.setFaceId(faceId);
236 command.append(parameters.wireEncode());
237
238 try {
239 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800240 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800241 throw new ManagementException(e.getMessage(), e);
242 }
243 }
244
245 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800246 * Enable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800247 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800248 * @param face only a localhost {@link Face}
249 * @param header the control feature to enable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800250 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
251 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800252 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800253 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800254 public static void enableLocalControlHeader(final Face face, final LocalControlHeader header) throws
255 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800256 // build command name
257 Name command = new Name("/localhost/nfd/faces/enable-local-control");
258 ControlParameters parameters = new ControlParameters();
259 parameters.setLocalControlFeature(header.toInteger());
260 command.append(parameters.wireEncode());
261
262 try {
263 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800264 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800265 throw new ManagementException(e.getMessage(), e);
266 }
267 }
268
269 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800270 * Disable a local control feature on the given forwarder.
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800271 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800272 * @param face only a localhost {@link Face}
273 * @param header the control feature to disable
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800274 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
275 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800276 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt">Face Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800277 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800278 public static void disableLocalControlHeader(final Face face, final LocalControlHeader header) throws
279 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800280 // build command name
281 Name command = new Name("/localhost/nfd/faces/disable-local-control");
282 ControlParameters parameters = new ControlParameters();
283 parameters.setLocalControlFeature(header.toInteger());
284 command.append(parameters.wireEncode());
285
286 try {
287 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800288 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800289 throw new ManagementException(e.getMessage(), e);
290 }
291 }
292
293 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800294 * Register a route on the forwarder.
295 * <p/>
296 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800297 * signing has been set up (e.g. forwarder.setCommandSigningInfo()).
298 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800299 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800300 * @param controlParameters the {@link ControlParameters} command options
301 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
302 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800303 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
304 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800305 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800306 public static void register(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800307 // build command name
308 Name command = new Name("/localhost/nfd/rib/register");
309 command.append(controlParameters.wireEncode());
310
311 try {
312 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800313 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800314 throw new ManagementException(e.getMessage(), e);
315 }
316 }
317
318 /**
319 * Register a route on a forwarder; this will create a new face on the
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800320 * forwarder towards the face (e.g., self registration).
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800321 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800322 * @param face only a localhost {@link Face}
323 * @param route the {@link Name} prefix of the route
324 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800325 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
326 * the NFD rejected the request
327 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800328 public static void register(final Face face, final Name route, final int cost) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800329 ForwardingFlags flags = new ForwardingFlags();
330 flags.setCapture(false);
331 flags.setChildInherit(true);
332
333 register(face, new ControlParameters()
334 .setName(route)
335 .setCost(cost)
336 .setOrigin(RouteOrigin.APP.toInteger())
337 .setForwardingFlags(flags));
338 }
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800339
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800340 /**
341 * Register a route on a forwarder; this will create a new face on the
342 * forwarder to the given URI/route pair. See register(Face,
343 * ControlParameters) for more detailed documentation.
344 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800345 * @param face only a localhost {@link Face}
346 * @param uri the URI (e.g. "tcp4://10.10.2.2:6363") of the remote node; note
347 * that this must be one of the canonical forms described in the wiki
348 * (http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#TCP) for NFD to
349 * accept the registration--otherwise you will see 400 errors
350 * @param route the {@link Name} prefix of the route
351 * @param cost the numeric cost of forwarding along the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800352 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
353 * the NFD rejected the request
354 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800355 public static void register(final Face face, final String uri, final Name route, final int cost) throws
356 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800357 // create the new face
358 int faceId = createFace(face, uri);
359
360 // run base method
361 register(face, faceId, route, cost);
362 }
363
364 /**
365 * Register a route on a forwarder; this will not create a new face since it
366 * is provided a faceId. See register(Face, ControlParameters) for full
367 * documentation.
368 *
369 * @param forwarder only a localhost {@link Face}
370 * @param faceId the ID of the {@link Face} to assign to the route
371 * @param route the {@link Name} prefix of the route
372 * @param cost the numeric cost of forwarding along the route
373 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
374 * the NFD rejected the request
375 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800376 public static void register(final Face forwarder, final int faceId, final Name route, final int cost) throws
377 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800378 // build command name
379 ControlParameters parameters = new ControlParameters();
380 parameters.setName(route);
381 parameters.setFaceId(faceId);
382 parameters.setCost(cost);
383 parameters.setOrigin(RouteOrigin.STATIC.toInteger());
384 ForwardingFlags flags = new ForwardingFlags();
385 flags.setCapture(false);
386 flags.setChildInherit(true);
387 parameters.setForwardingFlags(flags);
388
389 // run base method
390 register(forwarder, parameters);
391 }
392
393 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800394 * Unregister a route on a forwarder
395 * <p/>
396 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
397 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800398 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800399 * @param face only a localhost {@link Face}
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800400 * @param controlParameters the {@link ControlParameters} command options
401 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
402 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800403 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
404 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800405 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800406 public static void unregister(final Face face, final ControlParameters controlParameters) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800407 // build command name
408 Name command = new Name("/localhost/nfd/rib/unregister");
409 command.append(controlParameters.wireEncode());
410
411 try {
412 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800413 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800414 throw new ManagementException(e.getMessage(), e);
415 }
416 }
417
418 /**
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800419 * Unregister a route on a forwarder.
420 * <p/>
421 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800422 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
423 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800424 * @param face only a localhost {@link Face}
425 * @param route the {@link Name} prefix of the route
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800426 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
427 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800428 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
429 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800430 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800431 public static void unregister(final Face face, final Name route) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800432 // build command name
433 ControlParameters controlParameters = new ControlParameters();
434 controlParameters.setName(route);
435
436 // send the interest
437 unregister(face, controlParameters);
438 }
439
440 /**
441 * Unregister a route on a forwarder; see
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800442 * <p/>
443 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800444 * signing has been set up (e.g. forwarder.setCommandSigningInfo().
445 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800446 * @param face only a localhost {@link Face}
447 * @param route the {@link Name} prefix of the route
448 * @param faceId the specific ID of the face to remove (more than one face can
449 * be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800450 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
451 * the NFD rejected the request
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800452 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc</a>
453 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RIB Management</a>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800454 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800455 public static void unregister(final Face face, final Name route, final int faceId) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800456 // build command name
457 ControlParameters controlParameters = new ControlParameters();
458 controlParameters.setName(route);
459 controlParameters.setFaceId(faceId);
460
461 // send the interest
462 unregister(face, controlParameters);
463 }
464
465 /**
466 * Unregister a route on a forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800467 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800468 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
469 * signing has been set up using forwarder.setCommandSigningInfo().
470 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800471 * @param face only a localhost {@link Face}
472 * @param route the {@link Name} prefix of the route
473 * @param uri the URI (e.g. "tcp4://some.host.com") of the remote node (more
474 * than one face can be registered to a route)
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800475 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
476 * the NFD rejected the request
477 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
478 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/RibMgmt">RibMgmt</a>
479 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800480 public static void unregister(final Face face, final Name route, final String uri) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800481 int faceId = -1;
482 for (FaceStatus faceStatus : getFaceList(face)) {
483 if (faceStatus.getRemoteUri().matches(uri)) {
484 faceId = faceStatus.getFaceId();
485 break;
486 }
487 }
488
489 if (faceId == -1) {
490 throw new ManagementException("Face not found: " + uri);
491 }
492
493 // send the interest
494 unregister(face, route, faceId);
495 }
496
497 /**
498 * Set a strategy on the forwarder
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800499 * <p/>
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800500 * Ensure the forwarding face is on the local machine (management requests are to /localhost/...) and that command
501 * signing has been set up using forwarder.setCommandSigningInfo().
502 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800503 * @param face only a localhost {@link Face}
504 * @param prefix the {@link Name} prefix
505 * @param strategy the {@link Name} of the strategy to set, e.g.
506 * /localhost/nfd/strategy/broadcast
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800507 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
508 * the NFD rejected the request
509 * @see <a href="http://named-data.net/doc/NFD/current/manpages/nfdc.html">nfdc command-line usage</a>
510 * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StrategyChoice">StrategyChoice</a>
511 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800512 public static void setStrategy(final Face face, final Name prefix, final Name strategy) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800513 // build command name
514 Name command = new Name("/localhost/nfd/strategy-choice/set");
515 ControlParameters parameters = new ControlParameters();
516 parameters.setName(prefix);
517 parameters.setStrategy(strategy);
518 command.append(parameters.wireEncode());
519
520 try {
521 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800522 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800523 throw new ManagementException(e.getMessage(), e);
524 }
525 }
526
527 /**
528 * Set a strategy on the forwarder; see
529 * {@link #setStrategy(net.named_data.jndn.Face, net.named_data.jndn.Name, net.named_data.jndn.Name)}
530 * for more information. Ensure the forwarding face is on the local machine
531 * (management requests are to /localhost/...) and that command signing has
532 * been set up (e.g. forwarder.setCommandSigningInfo()).
533 *
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800534 * @param face only a localhost {@link Face}
535 * @param prefix the {@link Name} prefix
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800536 * @throws ManagementException if the network request failed, the NFD response could not be decoded, or
537 * the NFD rejected the request
538 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800539 public static void unsetStrategy(final Face face, final Name prefix) throws ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800540 // build command name
541 Name command = new Name("/localhost/nfd/strategy-choice/unset");
542 ControlParameters parameters = new ControlParameters();
543 parameters.setName(prefix);
544 command.append(parameters.wireEncode());
545
546 try {
547 sendCommand(face, command);
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800548 } catch (IOException | EncodingException | ManagementException e) {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800549 throw new ManagementException(e.getMessage(), e);
550 }
551 }
552
553 /**
554 * Send an interest as a command to the forwarder; this method will convert
555 * the interest to a command interest and block until a response is received
556 * from the forwarder. Ensure the forwarding face is on the local machine
557 * (management requests are to /localhost/...) and that command signing has
558 * been set up (e.g. forwarder.setCommandSigningInfo()).
559 *
560 * @param face only a localhost Face, command signing info must be set
561 * @param name As described at
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800562 * <a href="http://redmine.named-data.net/projects/nfd/wiki/ControlCommand">ControlCommand</a>,
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800563 * the requested interest must have encoded ControlParameters appended to the
564 * interest name
565 * @return a {@link ControlResponse}
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800566 * @throws IOException if the network request failed
567 * @throws EncodingException if the NFD response could not be decoded
568 * @throws ManagementException if the NFD rejected the request
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800569 */
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800570 private static ControlResponse sendCommand(final Face face, final Name name) throws IOException, EncodingException,
571 ManagementException {
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800572 Interest interest = new Interest(name);
573
574 // forwarder must have command signing info set
575 try {
576 face.makeCommandInterest(interest);
Alexander Afanasyev3c5ae7c2016-02-19 19:33:21 -0800577 } catch (NullPointerException | SecurityException e) {
Alexander Afanasyeve36e1af2016-02-19 18:06:05 -0800578 throw new IllegalArgumentException("Failed to make command interest; ensure command signing info is set on the " +
579 "face.", e);
Alexander Afanasyeva8bc0d82016-01-25 17:25:30 -0800580 }
581
582 // send command packet
583 Data data = FetchHelper.getData(face, interest.getName());
584
585 // decode response
586 ControlResponse response = new ControlResponse();
587 response.wireDecode(data.getContent().buf());
588
589 // check response for success
590 if (response.getStatusCode() != OK_STATUS) {
591 throw ManagementException.fromResponse(response);
592 }
593
594 return response;
595 }
596}