Service Virtualization

 View Only

Tech Tip: Dynamically Adding Headers to a REST Call 

Jul 17, 2018 11:00 AM

Overview and Background

In the majority of situations, developers create steps in DevTest and add parameterization using {{ }} notation to enable value substitution at run-time. There are situations, however, where the key-side of the key/value pair is unknown or undiscovered until run-time. When this situation occurs, an immediate challenge results: how does a step in a model dynamically insert an unknown key/value pair so the step execution can complete successfully?

 

The following tip describes one approach to adding HTTP header key/value pairs at run-time.

Special Note: As with any discussion of this type, developers should take care and completely understand their specific requirements prior to implementing these types of on-the-fly modifications as future versions of DevTest software could deprecate the ability to perform these actions.

 

The Setup

Let's say a Test Case has a REST step that makes a call to an endpoint. The call requires that the step include HTTP Header key/value pairs that are unknown at design time. We need the DevTest model to add these key/value pairs so the execution of the REST call can complete successfully. The headers are not static meaning that one call may send one header key/value pair and the next call may send multiple header key/value pairs. The challenge is that when the Test is modeled, we do not know which Header key/value pairs are required within the REST Step.

 

The REST Step Configuration 

First, let's look at the modeled REST step. Normal configuration requires that we have URL and other information. The Headers tab in this model is left blank for purposes of this example. The example is going to dynamically insert these header key/value pairs at run-time.

   

Data to Drive to Test

In order to demonstrate dynamic substitution, specific header information will be externalized in an Excel spreadsheet. The sole purpose of externalizing the data this way is to demonstrate that each call performed by the above REST step includes a different set of header information.

The dataset is setup to include three different header keys (e.g., headerKey1, headerkey2, headerKey3).

Each row contains the value side of the key value pair and represents three (3) different executions of the service call.

Three calls will be made to the endpoint. 

Each call must contain a different combination of header key/value pairs. For example, 

Call 1:  Sends  headerKey1=value1&headerKey2=value2&headerKey3=value3

Call 2:  Sends  headerKey3=valueZ

Call 3:  Sends  headerKey2=valueA 

 

Script Logic to Set the Dynamic Headers

The example now has the data to drive the test and the REST call to the endpoint. Now, we must add logic to marshal the header contents from the spreadsheet into the REST call headers. A sample project file is attached for those that want to look at the implementation specifics. The remainder of this section contains psuedo-code describing the actions performed by the script - which in this case is a JSR-223 step using Beanshell.

  • Identify the exact name of the REST call step in the model including upper and lower case. This name must be exactly as it is coded in the Test; else, DevTest cannot locate the step in order to successfully add the headers.  In this example, the Step Name is: "VarHeaderREST". 

CAUTION: If the step name changes, a code change must also be applied to reflect the name change.

  • Add logic to ignore Key/Value pairs that are empty. In this example, the logic excludes headers that do not contain information to be passed to the REST provider.
  • Establish a Key/Value pair ParameterList having only the values to be appended to the REST call for this execution and ensure proper "&" separation between key/value pairs (refer to Call 1, 2, and 3 above)
  • Set the ParameterList into the Step's headers (node name of VarHeaderREST) for use in the call 

CAUTION: This example replaces (not updates) the REST step headers with those generated in this code fragment.

 

Demonstrating the Example Works

In this example, all DevTest components are running on localhost.

The model as shown in the attachment under a Test Case name of VariableHeaders.tst appears as follows:

The test case will execute in a loop (3 times). Each pass through the loop will set a different combination of Header key/value pairs in the REST call.

For purposes of demonstrating that the example works, the VarHeaderREST step will be modified to point to a DevTest HTTP Recorder endpoint and the DevTest HTTP Recorder will pass the request to the server endpoint. 

The REST Step is modified as follows:

The DevTest Recorder is set up to record the Request / Response so we can see the headers.

Following is the recorder configuration:

 

Once the Recorder is configured and running, the Test Case can send transactions.

Execution was performed using ITR mode so each execution can be controlled and stopped.

The recorder is left running for the duration of the test.

Upon completion of each REST call to the endpoint, we can peak into the recorded content by double-clicking the correct GET / transaction, then CLICKing the Meta Data tab.

 

On the first execution, the Test sent all three header key/value pairs:

On the second execution, the Test sent only the key/value pair represented by headerKey3.

 

And, the third and final execution, the Test sent only key/value pair represented by headerKey2.

Adding this type of behavior to a model is unnecessary in the majority of situations; however, having a concept that enables the approach helps ensure that requirements can be achieved.

 

As noted above, ensure that the requirements specifically dictate that this type of implementation is required. As with any custom code-based solution, changes in the DevTest product can make the approach inoperable. 

Statistics
0 Favorited
18 Views
1 Files
0 Shares
5 Downloads
Attachment(s)
zip file
Dynamic_Headers.zip   14 KB   1 version
Uploaded - May 29, 2019

Tags and Keywords

Comments

Jul 21, 2018 07:58 AM

Thanks joel that's really helpful

Jul 20, 2018 09:30 AM

I know this can be challenging and frustrating at times.

The CA Communities will continue to be a good place to locate reference materials regarding extending DevTest. The custom FTP Step comes to mind (Can we do FTP recording in LISA ? How to create virtual services using FTP ? Is there any protocol like FTP. ). Check the ZIP attached within the thread for ideas on how custom steps are implemented.

 

Occasionally, a Communities contributor will post and attach a file. For example this DPH: The specified item was not found. I see that you have participated in some of these posts as well. Thank you for that. 

 

Check your local installation of DevTest for a directory (DevTest_HOME/doc) or scan for SDKJavaDoc.zip. Some of the Java docs are located in this file.

 

Continue to ask questions here on Communities.

 

Research docops (DevTest Solutions - Home - DevTest Solutions - 10.3 - CA Technologies Documentation ).

 

Work with your leadership and the CA Account team to determine if CA education or Services can be engaged to provide specialized, deep dive training.

 

Please keep in mind that extensions are not warrantied, integrated, hardened, tested, or supported as part of a prior, current or new product release. They are most often developed and tested in the narrow confines of a response to a customer-specific challenge. It is sometimes difficult to describe the nuances that might exist with regard to extension development. Perhaps, these are some reasons more information is not posted here in the forum.

Jul 20, 2018 01:23 AM

Great to learn this . I am struggling to write code for extending Deve test like dataset,protocol,Filter etc . We should have overall knowledge of all interfaces and classes being used by lisa . how can i get thorugh this ? 

Jul 17, 2018 06:28 PM

Good question.

In the SetHeaders JSR step, there is code: String RESTNodeName = "VarHeaderREST"; that sets the name of the step where the headers will be added. When this line executes, the variable RESTNodeName is set to the name of the Rest Step on which we want to add the headers. 

 

At execution time, the code fragment ( testExec.TestCase.getNode(RESTNodeName).setHeaderFields(p); ) asks the running instance of TestExec to locate the node having the name="VarHeaderREST" and the setHeaderFields method exposed at run time places the updated arguments into the headers .

 

If one opens the VariableHeaders.tst case in an editor, you will see the various nodes (i.e., steps) defined, and one of those nodes will be named "VarHeaderREST". Consider the following view of the test case at rest on the file system:

 

<TestCase name="VariableHeaders" version="5">

:

  <Node name="Show Headers" log=""

  :

  <Node name="SetHeaders" log="" type="com.itko.lisa.test.UserScriptNode"
  :
  <Node name="VarHeaderREST" log="" type="com.itko.lisa.ws.rest.RESTNode"
     version="3" uid="66395A46340E11E6860466E220524153" think="0"
     useFilters="true" quiet="false" next="Show Headers" >

     <url>http://ca.com:80/</url>
     <content-type/>
     <data-type>text</data-type>
     <httpMethod>GET</httpMethod>
     <onError>abort</onError>
     <encode-test-props-in-url>false</encode-test-props-in-url>
  </Node>

:

</TestCase>

 

If these Headers values had been coded in the REST step in the model, the Node would contain these headers as XML element values. Therefore, the node would contain:

  <Node name="VarHeaderREST" log=""
     :
    next="Show Headers" >

    <url>http://ca.com:80/</url>
    <content-type/>
    <data-type>text</data-type>
    <header field="HeaderValue1" value="value1" />
    <header field="HeaderValue2" value="valueABCD" />
    <httpMethod>GET</httpMethod>
    <onError>abort</onError>
    <encode-test-props-in-url>false</encode-test-props-in-url>
  </Node>

 

In other words, the testExec.TestCase.getNode(RESTNodeName).setHeaderFields(p) code is dynamically adding these headers into the Node inside the running instance of the TestExec object which is controlling the Test Case. The code does not add the values into the copy of the Test Case at rest on the file system.  

 

This rest is conjecture... But, I believe the lisa.VarHeaderREST.http.headers property is likely created based on TestExec's understanding of the XML elements inside the Node (VarHeaderREST) when the Test Case is loaded into memory. My guess would be that the setHeaderFields method does not update this property. This is one reason I demoed the behavior using the Recorder so the headers could be observed on the basis of how the HTTP request was packaged up and sent to the provider endpoint.       

Jul 17, 2018 05:55 PM

Hi J_NeSmith,

                                How is "testExec.TestCase.getNode(RESTNodeName).setHeaderFields(p);" in SetHeaders step is adding the headers in the Step Request of "VarHeaderREST step.Since,I did not see the header being added to the property "lisa.VarHeaderREST.http.headers" but appearing in the step request of VarHeaderREST step.

Vish 

Related Entries and Links

No Related Resource entered.