In this chapter I will use script I presented previously and also will execute some REST API methods using Firefox RESTClient extension mentioned if first chapter. Because output of debug can be extensive listings will contain only crucial parts.

Debugging REST API means checking particular component for errors or other logs that might be interested for us. Command execution require in first place declaration which component will be debugged.

Debugging REST API POST Method

As you can see REST Agent process in all message exchange between all components so it’s aware of everything that is happening. So from output we can easily check if parameters are parsed correctly and what responses it receive from other modules. Lets look on output when script from chapter XXXX is executed.

It all starts with decoding URI and then method that will be used on URI (lines 1 an 3) following by checking in privilege level is sufficient for specified user (line 5).

In lines 7-11 we see exact structure of JSON object that has been attached to method. In more complex scripts if we are unsure that we send JSON object with correct values this is a way to do this. It’s very useful because JSON object can be created based on multiple variables also fetched by other subroutines etc.

In our example in lines 13-16 we can see what that command line we specified in JSON object is simply executed internally on firewall. Agent process before sending will translate it into XML format as seen in lines 20-24. Response from LINA process ill also be in XML which is presented in lines 26-40 of the output. Because it’s internal communication we don’t have to worry about understanding the

Ok, but what is happening when we execute other method than CLI command via REST API? Yes and no. It all depends on method you will use. Commands will be displayed for methods PUT, POST, PATCH and DELETE. We won’t see this executing GET method.

In this example we execute PUT method that modifies static route entry (lines 1-3). Because this method requires parameters passed as JSON structure the JSON object passed as argument is visible in debug output in line 5. It’s not user friendly as this is raw code, bur you can use jsonviewer.stack.hu to convert it to user readable format and even display as nice tree-based structure.

There are 7 commands that will be execute via CLI by REST API Agent and are listed in output in lines 7-16. Those commands as previously are translated to XML format before internally sending to LINA process (lines 18-28).

Last line ends PUT process and includes status code of execution that is passed to REST Client.

If you looked at the output carefully you should notice on interesting thing. We execute PUT method. But if you look at 18 the actual method executed is POST. This is normal behavior because at the end REST API is nod doing dom magic using hidden firmware feature. All operation are based on CLI and proper parsing of returned values. POST is the method used both internally and by REST Client to execute the command.

Errors

All examples above were from methods that were executed properly. So let’s execute something that won’t be correctly processed by firewall. Let’s delete route that does not exist. In REST API routes are identified by unique identifiers which is passed as a last part of URI. To delete static route we execute following method using non-existing identifier.

DELETE http://172.16.1.51/api/routing/static/393359fa

First indicator of the problem is the return value. We received 404 instead of expected 204 (highlighted in line 64) as well as ERROR description (“RESOURCE-NOT-FOUND”) with full traceback log.

[ra agent error]: 2016-12-26 00:54:06,488 ERROR [base] RESOURCE-NOT-FOUND
Stack trace:
at com.cisco.pdm.rest.c.i.db.vb(RestletObjectResource.java:836)
at com.cisco.pdm.rest.c.i.db.b(RestletObjectResource.java:762)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.restlet.resource.ServerResource.doHandle(ServerResource.java:524)
at org.restlet.resource.ServerResource.delete(ServerResource.java:216)
at org.restlet.resource.ServerResource.doHandle(ServerResource.java:623)
at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:679)
at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:357)
at org.restlet.resource.ServerResource.handle(ServerResource.java:1014)
at org.restlet.resource.Finder.handle(Finder.java:246)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:84)
at org.restlet.Application.handle(Application.java:384)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
at org.restlet.Component.handle(Component.java:406)
at org.restlet.Server.handle(Server.java:516)
at org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:72)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)
at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:73)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:80)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:677)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:77)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:649)
at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:158)
at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:433)
at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:398)
at java.lang.Thread.run(Thread.java:745)
[ra agent event]: 2016-12-26 00:54:06,497 DEBUG [base] Exit c DELETE with status code 404