Debug a Policy

The Policy Manager provides several tools to help you debug your policy:
gateway83
The Policy Manager provides several tools to help you debug your policy:
  • Service Debugger:
    This tools lets you add break points and manually step through your policy. This helps you debug your policy much like debugging code.
  • Debug Trace Policy:
    This is a special policy that runs after each assertion is executed. It provides a wealth of additional data to help you troubleshoot your policy.
This topic describes how to use the Service Debugger or the Debug Trace Policy to debug a policy.
For more information about debugging a policy, see this useful tip on the CA Communities: https://communities.ca.com/blogs/oauth/2017/03/06/tip-of-the-week-tracing-policy
 
Working with the Service Debugger
 The Policy Manager has a built-in debugger that can help you troubleshoot your policies. This debugger behaves much like the debuggers available within programming environments, allowing you to:
  • Add or remove breakpoints
  • Step through a policy and view its path
  • Step into or over composite assertions
  • View values within context variables
  • Pause and resume debugging
Keep in mind the following before you debug a policy:
  • Only the main service policy and global policy fragments can be debugged. Aliases and all other policy types cannot be debugged.
  • Included policy fragments cannot be debugged on their own, but they can be debugged once inserted into a service policy or global policy fragment (using the "Step Into" function of the debugger).
  • Only the active and saved _Ref-1156461310 of a policy can be debugged. To debug another policy or version, close and reopen the debugger.
  • There can be only one active debugger session per policy per Gateway node. In a clustered environment, you can have one active debugger session per policy per node.
  • Encapsulated assertions cannot be stepped into.
  • Once the debugger is started, the next message that arrives at the service endpoint is sent to the debugger, regardless of port number. In a high traffic Gateway, consider creating a copy of the policy and start the debugger in the copied policy.
  • If the active version of a policy changes after a debugger is started, be sure to close and reopen the debugger to re-synchronize the debugger with the correct policy.
  • Be aware that the debugger is attached to a service on a 
    specific
     node. This means that if the debugger is started on only some (or one) node in a clustered environment, the load balancer may route a message to a node without the debugger attached. To prevent this from happening, start the debugger on all nodes for the service.
Security Roles
To use the Service Debugger, you must have debugger permission to the policy being debugged. The following predefined roles have this permission:
  • Administrator
    : Allows you to launch the debugger for all policies.
  • Manage Webservices:
     Allows you to launch the debugger for all policies.
  • Manage
     
    [name]
     
    Service:
     Allows you to launch the debugger for the named service only.
    Debugger access to any global policy fragments also require a separate "Manage [name] Policy" role. If the service policy contains an included fragment, you require Read permission to that fragment to view or step into that fragment.
  • Manage
     
    [name]
     
    Policy:
     Allows you to launch the debugger for the named global policy fragment only. If the service policy contains an included fragment, you require Read permission to that fragment to view or step into that fragment. Note: For all other fragment types, this role has no impact on the Service Debugger.
For more information about the predefined roles, see Predefined Roles and Permissions.
 The "Service Debugger" option is not visible for unsupported roles. It is currently not possible to add debugger permissions to custom roles.
Running the Service Debugger
To debug a policy:
  1. Right-click a policy in the services and policies list and then select 
    Service Debugger
    . The active version of the policy is loaded into the Service Debugger dialog.
    Only the main service policy and global policy fragments can be debugged. All other policy types cannot be debugged and will not display the "Service Debugger" option. You must have debugger permission for the given policy to see the debugger option. 
     image2014-9-15 12:14:25.pngThe top pane displays the policy that was active when the Service Debugger was open. Once debugging begins, the bottom pane shows the context variables in use by the policy, with their values at the particular point in the policy. For more information, see Using the Context Variables Tree. 
    You may resize the Service Debugger dialog and alter the size of each pane by dragging the split bar separating the two panes.
  2. Add one or more breakpoints to the policy. This allows you to temporarily pause policy processing to examine the results. For more information, see Using Breakpoints.
  3. Optionally add more context variables that you wish to inspect to the variables tree in the bottom pane. For more information, see Using the Context Variables Tree.
  4. Click [
    Start
    ] (
    shortcut key: [F1]
    ) to start the debugging monitor. The Service Debugger will wait for the next message destined for the service endpoint. When a message arrives, it is sent to the debugger and is processed by the policy until it reaches the first breakpoint, at which point processing is suspended. If no breakpoints are defined, then the message runs to the end of the policy.
  5. When processing pauses at a breakpoint, you can choose to use one of the stepping options to manually step through the assertions or click [
    Resume
    ] to resume processing until the end of the policy or the next breakpoint is reached, whichever comes first. For more information, see Stepping Through the Policy.
  6. When the policy finishes executing, a message is displayed in the status area at the bottom of the dialog.
    • If the policy executed successfully, the message will read "Policy completed successfully".
    • If the policy did not complete successfully, the message describes the failure and the line number where it occurred; for example: "Policy completed with error. Assertion Falsified: assertion number 27".
At this point, you can choose to do any of the following:
  • Click [
    Start
    ] to restart debugging monitoring again.
  • Modify your breakpoints or list of context variables before restarting monitoring.
  • Click [
    Close
    ] to dismiss the Service Debugger dialog and then alter the policy before debugging again.
You can click [
Stop
] (
shortcut: Shift+[F1]
) at any time to stop the debugging. 
Using Breakpoints
Breakpoints allow you to suspend processing of a message at a particular point in the policy. This allows you to examine the values of context variables used in the policy or to manually step through the policy. 
Breakpoints are discarded when you close the Service Debugger dialog. Breakpoints cannot be added to the Add Comment to Policy assertion or for any disabled assertion in the policy. Breakpoints added to assertions within the Run All Assertions Concurrently assertion is ignored during debugging. (4) Breakpoints inside of composite assertions can affect how the "stepping" controls work. See Stepping Through the Policy for more details.
You can set a breakpoint in any number of ways:
  • Click in the white space between the line number and assertion name in the top pane.
  • Right-click an assertion and select 
    Toggle Breakpoint
    .
  • Select an assertion and then click [
    Toggle Breakpoint
    ].
You can clear a breakpoint in any number of ways:
  • Click the breakpoint icon next to the assertion name.
  • Right-click an assertion and select 
    Toggle Breakpoint
    .
  • Select an assertion and then click [
    Toggle Breakpoint
    ].
  • Click 
    [Remove All Breakpoints
    ] to delete all breakpoints at once. This is useful if you wish to replace all existing breakpoints with new ones.
    Breakpoints are not saved when the debugger is closed, so it is not necessary to clear the breakpoints before returning to your policy.
When processing is paused at a breakpoint, the assertion is highlighted in yellow to indicate the progress of the message. Choose one of the "stepping" options below to continue.
Stepping Through the Policy
When processing is paused at a breakpoint, you can use one of the stepping options to manually step through the policy.
If breakpoints exist inside a composite assertion or included policy, they take precedence over the stepping hierarchy. See examples below for more details. 
Step Over
Click [
Step Over
] to step to the next non-disabled assertion 
at the same level
. For composite assertions, [Step Over] will move to the composite assertion parent, then to the next equal-level assertion immediately after the composite assertion. 
Shortcut key: [F3]
For example, consider the following:
Assertion 1 <-- breakpoint here Assertion 2 (composite assertion or policy fragment) Child A Child B Child C Assertion 3
This is how [Step Over] will behave:
  • Assertion 1 --> Assertion 2 --> Assertion 3
  • If also breakpoint at Child A: 
    Assertion 1 --> Assertion 2 --> Child assertion A --> Assertion 3
  • If also breakpoints at Childs A & C: 
    Assertion 1 --> Assertion 2 --> Child A --> Child C --> Assertion 3
Step Into
Click [
Step Into
] to step to the next non-disabled assertion, regardless of hierarchy. 
Shortcut key: [F2]
It is not possible to step into the Run All Assertions Concurrently assertion or an encapsulated assertion. Clicking [Step Into] in this case will have the same effect as [Step Over].
Step Out
Click [
Step Out
] if you wish to exit processing a composite assertion. This will select the next parent-level assertion. 
Shortcut key: Shift+[F3]
For example, consider the following:
Assertion 1 Assertion 2 (composite assertion or policy fragment) Child A Child B <-- breakpoint here Child C Assertion 2a (composite assertion or policy fragment) Child D Child E Assertion 3
This is how [Step Out] will behave:
  • From 
    Child B --> Assertion 3
  • If also breakpoint at Child D: 
    Child B --> Child D --> Assertion 3
  • If also breakpoints at Child D & E: 
    Child B --> Child D --> Child E --> Assertion 3
Stepping out within a Run Assertions for Each Item assertion will step out of the 
current loop only
, not the entire assertion. If there are more iterations remaining in this assertion, the debugger will enter the loop again and then stop at the next breakpoint within that assertion (if one exists). 
Resume
Click [
Resume
] to continue processing based on the policy logic. Processing continues until the next breakpoint or the end of the policy, whichever comes first. (
shortcut key: [F4]
)
Stop
Click [
Stop
] to stop debugging, but leave the Service Debugger dialog open. Policy processing continues in the background until the end of the policy is reached.
Using the Context Variables Tree
The context variables tree displays the context variables that have been set as of a particular breakpoint. It offers an easy way to "peek" into a variable in real time during processing. The context variables are listed in the following format:
name = {dataType} "value"
Where:
  • name
     is the name of the context variable
  • dataType
     is the Java class name of the context variable (for example: String, Integer, Message, ArrayList)
  • value
     is the value of the variable at that particular breakpoint
Example:
error.status = {String} "403"
(1) The context variables are listed in alphabetical order. (2) You can copy any line in the context variables tree by selecting it and pressing Ctrl-[C]. Note that child nodes need to be specifically selected (use the Shift or Ctrl keys to select). (3) The context variables are retained when the debugger stops, but are cleared when the debugger is started again. 
Message Variables
For context variables of type Message, child nodes display the values for the attributes of the message; for example: 
image2014-10-1 16:28:50.png
Interpreting the example above:
  • The context variable is a request message, where "request" is the root node of the variable. All information about this variable are given in the child nodes.
  • The three context variables for this message are:
  • request.contentType
     
  • request.http.allheadervalues
     
  • request.mainpart
These three variables are automatically shown in the context variables tree as you step through the policy.
  • The variable 
    request.http.allheadervalues
     is an array containing seven values. The child nodes list of the value of all the headers in the message.
List Variables
For context variables of type List or Array, child nodes display the value of each index. For an example, see "http.allheadervalues".
Context Variable Exceptions
Context variables set by the Evaluate Request XPath and Evaluate Response XPath assertions will not show in the context variables tree unless these context variables are used later in the policy. To make these variables visible, add an assertion to the policy that uses these variables (for example, the Export Variables from Fragment assertion). 
Context variables set by the Require WS-Addressing assertion will show in the context variables tree only if a prefix is defined in the WS-Addressing Properties (a prefix is optional for this assertion). Exception: The 
${<prefix>.elements}
 variable is displayed in the context variables tree only if it is used later in the policy. 
Searching for a Context Variable
To quickly locate a context variable, type the first few characters of its name in the Search box to display all matching variables. You can jump to a variable by clicking on the displayed name or by selecting it using the Up/Down arrow keys followed by the [
Enter
] key. 
The following are some search tips:
  • The search is not case sensitive.
  • The search matches the typed text anywhere within the variable name.
  • Only variable names are matched; variable values are not included in the search.
  • For nested variables, only the child portion of the name is matched. For example, the full name for the "contentType" variable is actually "request.contentType". However you need to search for "contentType", not "request.contentType".
Manually Adding Context Variables
In addition to the context variables set in the policy, you can also manually add other context variables to the variable tree. This allows you to view other built-in variables that are not displayed by default in the tree or to examine any custom context variables. 
Context variables may be added while the debugger is running or stopped.
Manually added variables are not saved in the context variable tree when the debugger is closed.
To manually add another built-in context variable:
  1. Choose the variable from the drop-down list below the context variable tree. For a description of the variables, see Context Variables.
  2. Click [
    Add
    ]. The variable is added to the tree and is shown in blue to indicate a manually added variable. The variable has an empty value initially, until the debugger resumes.
To specify a custom context variable:
  1. Type in the name of the custom variable in the drop-down list box, with or without the "${ }" wrapper characters. The on-screen validator checks the syntax of the variable.
  2. Click [
    Add
    ]. The variable is added to the tree and is shown in blue to indicate a manually added variable. The variable has an empty value initially, until the debugger resumes.
To remove a manually added variable from the tree:
  • Right-click the variable and then select 
    Delete
    .
Variables that are displayed by default (that is, those not manually added) cannot be removed.
Debug Trace Policy
The Policy Manager has a special "trace policy" that can be invoked to help you diagnose and troubleshoot problems in a service policy, for both SOAP and non-SOAP services. When enabled, this trace policy executes after each assertion has completed within the service being debugged. The following is a partial list of the information that is passed to the trace policy for the assertion that just finished executing:
  • service entity ID
  • service ordinal
  • policy entity ID
  • policy ordinal
  • assertion status
For a complete list of information available to the trace policy, see Context Variables in Debug Trace Policy.
Enable policy debug tracing only for troubleshooting purposes. Do not enable it for production use. As the trace policy is run for each assertion in the policy, performance is significantly degraded.
Debug Tracing with an Audit Sink
For a comprehensive debugging solution, you can configure an audit sink to be run in addition to a debug trace policy. This will help troubleshoot issues such as the service policy terminating unexpectedly with a serious policy exception. When a policy terminates abnormally, debug tracing also stops. The addition of an audit sink lets you take some action after the termination.
If an audit sink is configured, it will be invoked after a request has finished processing. However, be aware that the audit sink policy cannot access any of the context variables created by the debug trace policy.
For more information on using audit sinks, see Managing the Audit Sink and Working with the Audit Sink Policy.
To enable policy debug tracing:
  1. Open the properties for the service being debugged.
  2. In the [General] tab, select the
    Enable policy debug tracing
    check box.
  3. Click [
    OK
    ]. You are asked whether you wish to edit the debug trace policy.
    • Click [
      Yes
      ] to open the trace policy for editing. You have a chance to save any currently open policy as a new revision.
    • Click [
      No
      ] to continue working in the current policy. You can edit the trace policy later by opening [Internal Debug Trace Policy] from the Services and Policies list.
      There is a default trace policy that you can use right away without further configuration.
Once tracing is enabled, the trace policy is run every time an assertion completes in the service policy. The performance impact depends on the complexity of the trace policy, but it will likely be significant.
Tip: To allow debug tracing to access the assertions within the underlying policy fragment ("backing policy") of an encapsulated assertion, you must select the "Allow debug tracing into backing policy" check box in the Encapsulated Assertion Configuration Properties.
Working with the Debug Trace Policy
A special trace policy is available to help you troubleshoot a service policy. This trace policy is enabled by selecting the Enable policy debug tracing check box in the [General] tab of the Service Properties. Any existing trace policy is used, otherwise one is created.
You can also use the Service Debugger to help you troubleshoot your policies. For more information, see Working with the Service Debugger.
When the tracing policy is enabled, it appears in the Services and Policies list on the Policy Manager interface with the name "[Internal Debug Trace Policy]", which is fixed and cannot be changed.
image2014-9-15 13:1:16.png
When enabled, the trace policy is executed once for each assertion that completes in the target policy.
The following characteristics are unique to the debug trace policy:
  • There is a single trace policy shared by all published services that have tracing enabled.
  • The debug trace policy is edited like a normal policy, but cannot be deleted while it is in use (i.e., enabled in the Service Properties of any published service).
  • The debug trace policy can access a large number of debug-specific context variables that exist only while the trace policy is active. See Context Variables for the Debug Trace Policy for details.
  • The debug trace policy uses the same audit context as the policy being traced. For example, audit detail messages added during tracing is combined with the detail messages from the target policy.
  • The properties for a debug trace policy cannot be modified.
  • The debug policy can optionally trace into the underlying policy fragment of an encapsulated assertion. For details, see Encapsulated Assertion Configuration Properties.
Aside from the above exceptions, the debug trace policy is configured and edited in similar fashion to an ordinary policy. Multiple policy revisions may be created and you may export or import the debug trace policy.
Deleting the Debug Trace Policy
When the debug trace policy is no longer required, you can delete it by right-clicking it in the Services and Policies list and selecting
Delete Policy
. Note that you cannot delete the trace policy if debug tracing is still enabled on any policy.
If you delete the debug trace policy, it will be recreated the next time policy debug tracing is enabled. However note that this is an entirely new trace policy—it will not have access to any policy revision history from the previously deleted trace policy. Do not delete the trace policy if you wish to keep its revision history.
Understanding the Debug Trace Policy
When the debug trace policy is enabled for the first time, it is created with the simple default policy (line wraps under "Audit Details" have been added for clarity):
image2014-10-1 16:34:39.png
The default trace policy can be used immediately, without modification. It will do the following:
  1. Enables auditing with the Audit Messages in Policy assertion.
  2. Adds the following details to the audit record via the Add Audit Detail assertion:
  • name of the service
  • name of the policy
  • GUID of the policy
  • number of the assertion within the policy
  • name of the assertion
  • status returned by the assertion
These details are retrieved from the corresponding debug trace context variables, described below. You may edit the default trace policy as necessary.
More Complex Example
The following is a more complex trace policy that collects trace information for an entire request as a batch, then email it to someone, sending no more than one email per traced request:
Set Context Variable: ${trace.out} = "${trace.out} TRACE: service.oid=${trace.service.oid} assertion.number=${trace.assertion.numberstr} policy.guid=${trace.policy.guid} assertion.shortname=${trace.assertion.shortname} status=${trace.status}\n" At Least One Assertion Must Evaluate to True All Assertions Must Evaluate to True Compare Expression: ${trace.final} == "true" Send Email Alert: [email protected]: subject=Debug trace for policy body="${trace.out}" Continue Processing
In this more complex example, a new line beginning with "TRACE:" is appended to the
${trace.out}
context variable each time the trace policy is invoked for a request. When the debug trace is complete (
${trace.final}
returns "true"), the contents of the
${trace.out}
variable is emailed to [email protected]
Though the trace policy can be as complex and full featured as any normal service policy, it is highly recommended to keep it as short and basic as possible. Remember, the full trace policy will be executed each time an assertion completes in the target policy.
Saving Trace Information to a File
To save the trace information to a log file:
  1. Using the Manage Log Sinks task, create a new log sink with the following properties:
    Name: 
    trace
    Description: 
    Save trace information to a file
    Type: 
    File
    Severity Threshold: 
    All
    Selected Categories: 
    Gateway Log, Audits
     (hold down [Ctrl] key to select both) 
     
  2. Using the Manage Cluster-Wide Properties task, add the cluster property log.levels with the following line appended to the value:
    com.l7tech.server.trace.TracePolicyEvaluator.level = FINER
  3. Configure your trace policy to accumulate any desired trace information in the context variable ${trace.out}. For example, the policy sample under "
    More Complex Example
    " above is a good example.
  4. When service consumption is complete, you can find the trace log file in this directory:
    /opt/SecureSpan/Gateway/node/default/var/logs 
Security Permissions
In order to edit a Debug Trace Policy, you must have one or more roles that grant permission for:
  •  Managing services
  •  Managing policies
  •  Managing cluster-wide properties
These can be either predefined roles or custom roles with the appropriate permissions.
Context Variables in Debug Trace Policy
The following context variables contain values only when used in a debug trace policy, or within a policy fragment that is included in a debug trace policy. If called from any other policy, these variables do not exist and are interpolated as blank (unless the
template.strictmode
cluster property is enforced, in which case the calling assertion fails).
Variable
Description
trace.service.oid
The internal object identifier of the published service with the policy currently being traced.
trace.service.name
The name of the published service with the policy currently being traced.
trace.policy.guid
The GUID of the policy containing the assertion that just executed.
trace.policy.name
The name of the policy containing the assertion that just executed.
trace.policy.version
The policy version number that is active in the policy containing the assertion that just executed.
trace.assertion.number
This is a multivalued variable that contains the full path to the traced assertion, with each position in the path as a separate value. For example, for "3.2.17 Compare Expression", this variable contains the values "3", "2", "17".
trace.assertion.numberStr
Similar to trace.assertion.number above, except the full path is recorded as an assertion number; for example, "3.2.17".
trace.assertion.ordinal
The ordinal of the assertion within its policy fragment. Using the "Compare Expression" example under trace.assertion.number above, this will be "17".
trace.assertion.shortName
The short name of the assertion; for example "Continue Processing".
trace.assertion.xml
The raw XML code for the assertion; useful for deeper inspection.
Use this variable carefully, as it will further impact system performance during debug tracing.
trace.status
The assertion status code returned by the assertion that just finished. A status of "0" means the assertion succeeded. Any other status means the assertion failed.
trace.status.message
The text from the assertion status code message; for example, "Authentication Failed".
trace.request
The original request message from the policy being traced.
trace.response
The original response message from the policy being traced.
Take care not to modify the original request or response within the trace policy to avoid affecting the behavior of the policy being traced. Even strictly read-only operations like XPath or schema validation may affect the exact behavior of the original policy in subtle ways by changing how and when the XML is parsed or the data is read.
trace.var.
<variableName>
Returns the contents of the
${variableName}
context variable from the policy being traced. The
${variableName}
variable can be any context variable that has been set in the policy up to that point.
trace.final
This variable is set to "true" for the final trace invocation, after the last assertion has finished for this request.
trace.out
This is a special utility variable that is empty initially. It is normally used to accumulate trace information during debug tracing.