Loading…
Loading…
Provides stateless helper methods for classifying traffic payloads, generating canonical keys for services, and extracting details from SOAP and XML
The TrafficDerivationCore is an internal library of stateless, vendor-agnostic helper methods for analyzing observed API traffic. It provides a canonical implementation for common tasks required by traffic-learning services, such as classifying payload types, generating stable identifiers for services and requests, and extracting specific details from SOAP and XML payloads.
This component solves the problem of code duplication between different traffic-learning curators (e.g., F5TrafficLearningService and GenericTrafficLearningService) by centralizing pure, side-effect-free logic. Its functions are called by these services during the processing of ingested traffic data.
Inputs to these methods are typically raw data from traffic logs, such as request payloads, URIs, and backend connection details. Outputs are standardized classifications, canonical strings, or extracted data used for bucketing, deduplication, and generating learned API examples.
NOTE
The scope of this component is deliberately narrow. It contains only pure, stateless helper functions. Logic that depends on instance-specific state, topology information, or database access remains in the calling services.
The TrafficDerivationCore provides utilities that operate in several key areas: payload classification, canonical signature generation, and payload content analysis.
To determine how to process a request, the system first classifies its payload. The classifyRequestPayload method performs a series of fast, ordered checks on the payload string to assign it a PayloadKind.
This classification runs on every ingested traffic event before any expensive parsing is attempted. The order of checks is critical to ensure correctness. For example, a SOAP envelope is also valid XML, so the SOAP check must occur first.
The classification logic follows this sequence:
flowchart TD
subgraph Payload Classification Flow
A[Start: payload string] --> B{Is payload null or empty?};
B -- Yes --> C[Return PayloadKind.NONE];
B -- No --> D{Does payload contain ':envelope' or '<envelope'?};
D -- Yes --> E[Return PayloadKind.SOAP];
D -- No --> F{Does payload start with '{' or '['?};
F -- Yes --> G[Return PayloadKind.JSON];
F -- No --> H{Does payload start with '<'?};
H -- Yes --> I[Return PayloadKind.XML];
H -- No --> J[Return PayloadKind.NONE];
endThe resulting PayloadKind determines how the traffic-learning curator will handle the request.
To group and deduplicate observed requests, the system generates stable, canonical signatures.
A service_backend_key uniquely identifies a backend service endpoint. The computeServiceBackendKey method constructs this key from a scheme, host, and port. The format is scheme://host[:port], with default ports (80 for http, 443 for https a) omitted. If the scheme is not provided, it is inferred from the port. This ensures that the same backend service is identified consistently, regardless of which traffic source observed it.
For bodyless REST calls (e.g., GET), a canonical signature is needed to group similar requests. The canonicalRestSignature method generates this signature by normalizing the HTTP method and URI.
The process discards query parameter values and the URI fragment, then sorts the parameter names alphabetically. This collapses many unique URIs into a single signature representing a distinct call shape.
NOTE
Query parameter values are deliberately discarded. This prevents the system from creating a new, unique example for every call to a busy endpoint where parameters like session IDs or tracking references change frequently. This focuses on the API's structural signature.
The normalization process is as follows:
flowchart TD
subgraph REST Signature Generation
A[Start: method, uri] --> B[Normalize method to uppercase];
B --> C[Trim URI and remove fragment (#...)];
C --> D[Split URI into path and query string];
D --> E{Query string exists and is not empty?};
E -- No --> F[Result: "METHOD path"];
E -- Yes --> G[Split query string by '&'];
G --> H[For each pair, extract parameter name];
H --> I[Collect unique, non-blank names];
I --> J[Sort parameter names alphabetically];
J --> K[Join names with '&'];
K --> L[Result: "METHOD path?name1&name2..."];
endGiven the following request:
get/users/search?name=alice&sort=asc&name=bob#resultsThe canonicalRestSignature method would produce the following signature:
GET.#results is removed. The URI is now /users/search?name=alice&sort=asc&name=bob./users/search.name=alice&sort=asc&name=bob.name, sort.name, sort.GET /users/search?name&sortFor structured payloads like SOAP and XML, helper methods are available to extract key information.
resolveSoapOperationName performs a full, namespace-aware DOM parse of a SOAP payload to find the local name of the first element inside the <soap:Body>. This is used to identify the specific SOAP operation being invoked. To prevent XXE vulnerabilities, DOCTYPE declarations are disabled during parsing.resolveXmlRootName uses a fast substring scan to find the name of the root element. This is less expensive than a full DOM parse and is used for naming learned examples.looksLikeSoapFault uses a cheap substring check to quickly determine if a response payload contains a SOAP Fault. This avoids a second expensive DOM parse on the response path.WARNING
The looksLikeSoapFault method uses a substring search for performance. There is a small risk of false positives if a non-fault payload contains terms like <faultcode> or <fault>. This trade-off is considered acceptable for its role in gating whether an example is useful.
The TrafficDerivationCore exposes the following static methods.
classifyRequestPayloadClassifies a request payload string into a PayloadKind based on its format.
| Parameter | Type | Description |
|---|---|---|
payload | String | The raw request body payload to classify. |
Returns: A PayloadKind enum value: SOAP, XML, JSON, or NONE.
PayloadKind EnumThis enum represents the derived shape of a request payload.
| Value | Wire Name | Description |
|---|---|---|
SOAP | soap | A SOAP 1.1 or 1.2 envelope. |
XML | xml | A well-formed XML document that is not a SOAP envelope. |
JSON | json | A JSON object or array. |
NONE | none | The request has no body, or the body is of an unusable format (e.g., binary). |
computeServiceBackendKeyComputes the canonical service_backend_key for a backend endpoint.
| Parameter | Type | Description |
|---|---|---|
scheme | String | The protocol scheme (e.g., http, httpshttps). If blank, it's inferred from the port. |
host | String | The hostname or IP address of the backend. |
port | Integer | The port number. Default ports (80 for http, 443 for https) are omitted from the output. |
Returns: A string in the format scheme://host[:port], or an empty string if host is null or blank.
canonicalRestSignatureGenerates a stable, canonical signature for a bodyless REST call.
| Parameter | Type | Description |
|---|---|---|
requestMethod | String | The HTTP request method (e.g., GET, POST). Defaults to GET if blank. |
uri | String | The full request URI, including the query string. |
Returns: A normalized string signature in the format METHOD path?param1¶m2....
resolveSoapOperationNameExtracts the SOAP operation name from a payload by parsing the document and finding the first element inside the SOAP Body.
| Parameter | Type | Description |
|---|---|---|
payload | String | The full SOAP envelope payload. |
Returns: The local name of the SOAP operation element, or an empty string if parsing fails or the operation cannot be found.
resolveXmlRootNameExtracts the local name of an XML document's root element using a fast substring scan.
| Parameter | Type | Description |
|---|---|---|
payload | String | The XML document payload. |
Returns: The name of the root XML element, or an empty string if it cannot be determined.
looksLikeSoapPerforms a quick, case-insensitive substring check to see if a payload appears to be a SOAP envelope.
| Parameter | Type | Description |
|---|---|---|
payload | String | The request or response payload. |
Returns: true if the payload contains :envelope or <envelope, false otherwise.
looksLikeSoapFaultPerforms a quick, case-insensitive substring check to see if a payload appears to be a SOAP Fault.
| Parameter | Type | Description |
|---|---|---|
payload | String | The SOAP payload. |
Returns: true if the payload contains fault-related tags (e.g., <fault>, <faultcode>), false otherwise.
isBodylessMethodChecks if a given HTTP method is one where an empty request body is normal.
| Parameter | Type | Description |
|---|---|---|
requestMethod | String | The HTTP request method. |
Returns: true for GET, HEAD, DELETE, and OPTIONS; false otherwise.
sha256HexComputes the SHA-256 hex digest of a string.
| Parameter | Type | Description |
|---|---|---|
value | String | The string to hash (UTF-8 encoded). |
Returns: A hex-formatted string representing the SHA-256 digest.
extractLeafFieldsExtracts a list of leaf-field samples from a SOAP payload. This is a pass-through to the SoapPayloadExtractor component.
| Parameter | Type | Description |
|---|---|---|
payload | String | The SOAP request or response body. |
maxLeaves | int | The maximum number of leaf fields to return. |
Returns: A List of SoapPayloadExtractor.LeafField objects.
findChildByLocalNameFinds the first child Element of a parent Element that has a specific local name.
| Parameter | Type | Description |
|---|---|---|
parent | Element | The parent DOM element to search within. |
localName | String | The local name of the child element to find. |
Returns: The matching Element, or null if not found.
| Method | Condition | Outcome |
|---|---|---|
computeServiceBackendKey | The host parameter is null or a blank string. | Returns an empty string. |
resolveSoapOperationName | The payload is not well-formed XML, or the SOAP Body or its first element child cannot be found. | Returns an empty string. Any Exception during parsing is caught. |
resolveXmlRootName | The payload does not appear to contain a valid XML root element tag. | Returns an empty string. |
sha256Hex | The SHA-256 message digest algorithm is not available in the Java Security Provider configuration. | Throws an IllegalStateException. This indicates a severe JVM configuration issue. |
findChildByLocalName | The parent element is null or no matching child element is found. | Returns null. |
F5TrafficLearningServiceGenericTrafficLearningServiceSoapPayloadExtractor