Skip to content

Wilma Extras: Sequence Handling

Tamás Kőhegyi edited this page Jun 17, 2022 · 7 revisions

What does Sequence mean in Wilma?

Wilma offers to collect and group request-response pairs into Sequences.

A Sequence object is a set of Request-Response pairs.

You can use this technique - among others - to save the history of communication and use this history when you create a stubbed response.


Defining Sequences in Stub Configuration

You can define sequence types, inside sequenceDescriptors array of wilmaStubConfiguration object.

 "sequenceDescriptors": [
      {
        "name": ...,
        "class": ...,
        "timeout": ...,
        "conditionDescriptor": { ... },
        "dialogDescriptorNames": [ ... ],
        "parameters" : [ ... ]
      },
      ...
    ]

Fields of a sequenceDescriptor item:

  • "name": it has to be unique. It’s REQUIRED and it must NOT contain the Forbidden characters
  • "class": it has to be a full name of a class which implements the com.epam.wilma.domain.stubconfig.sequence.handler.SequenceHandler interface and it’s found either on the class path or in an uploaded external source. It’s REQUIRED!
  • "timeout": it’s a time value in Milliseconds. It shows how long the sequence object won’t be expired without any interaction. It’s OPTIONAL! There is default value which comes from wilma.conf.properties file (sequence.default.timeout parameter). This value doesn't mean that the sequence will be cleaned after it has become expired. Those sequence objects will be cleaned which are expired when cleaning task runs.
  • "DialogDescriptorNames": an array of name objects those refer to an existing dialogDescriptor by its name. The specific sequenceDescriptor object and the referred dialogDescriptor has to be in the same configuration file.
  • "parameters": an optional parameter list for the specific sequenceDescriptor. All method of the SequenceHandler class gets these parameters.

Example wilmaStubConfiguration that contains sequenceDescriptors array:

{
  "wilmaStubConfiguration": {
    "sequenceDescriptors": [
      {
        "name": "somethingAnythingNothing",
        "class": "com.epam.wilma.sequencesandbox.ExternalDummySequenceHandler",
        "conditionDescriptor": { "condition": { "class": "AlwaysTrueChecker" } },
        "dialogDescriptorNames": [ { "name": "error-pattern-descriptor" } ],
        "parameters": [ { "name": "extra-header-key", "value": "sq-end" } ]
      }
    ],
    "dialogDescriptors": [
      {
        "name": "error-pattern-descriptor",
        "usage": "always",
        "comment": "random comment",
        "conditionDescriptor": {  "condition": { "class": "AlwaysFalseChecker" } },
        "responseDescriptor": {
          "code": 502,
          "delay": 0,
          "mimeType": "text/plain",
          "templateName": "errorResponse"
        }
      }
    ],
    "templates": [
      {
        "name": "errorResponse",
        "resource": "Bad Gateway",
        "type": "text"
      }
    ]
  }
}

SequenceHandler implementation

Any class which implements SequenceHandler interface has to define two methods. The job of methods are in the JavaDoc of the interface. Using a single SequenceHandler class by more than one SequenceDescriptor is possible. There's a built-in class that implements the SequenceHandler interface, its name is SessionIdBasedSequenceHandler. Further custom implementation can be used too, by implementing the necessary interface.

WilmaSequenceId

Specification: WilmaSequenceId = SequenceDescriptorKey + “|” + HandlerKey where SequenceDescriptorKey = Groupname + "_" + SequenceDescriptorName

  • HandlerKey is generated by SequenceHandler, it’s unique among those keys which were generated by the same handler class. This key must not contain Forbidden characters!

Forbidden characters

  • "|" ";" in name attribute of sequenceDescriptor and groupName field of "wilmaStubConfiguration" and HandlerKey

There is a validation method in the sequence handling process, so if a SequenceHandler generates a key that contains any of these forbidden characters, Wilma will write error messages to it's log file, and the sequence won't be created/used. The error log message contains the wrong key and the name of the broken SequenceHandler class.


Sequence handling logic

If the Sequence handling function is ON, Wilma checks every request whether it belongs to a SequenceDescriptor or not. If it does, Wilma will put a SequenceId into a header parameter of the request. SequenceId identifies the sequence object of the response.

It’s possible that a request belongs to more than one SequenceDescriptor. In the case of it, this header parameter contains more than one SequenceId and this request is stored in more than one Sequence object.

But a request belongs to only one sequence object in the same SequenceDescriptor.

Sequence handling - if it is ON - works in all operation modes (STUB, WILMA and PROXY).

Sequence handling does not work, when Message Logging is turned off. In this case the responses are not collected to the sequences, and stub response generation is not possible. See issue #45 too.


Using sequences

You can refer a sequence descriptor in responseDescriptor.

{
  "wilmaStubConfiguration": {
    "sequenceDescriptors": [
      {
        "name": "sequenceDescriptorName",
        "class": "com.epam.message.sequence.test.SingleSequenceHandler",
        "timeout": 120000,
        "conditionDescriptor": { "condition": { "class": "AlwaysTrueChecker" } }
      }
    ],
    "dialogDescriptors": [
      {
        "name": "super-descriptor",
        "usage": "always",
        "comment": "random comment",
        "conditionDescriptor": {  
            "condition": { "class": "com.epam.message.sequence.test.SimpleBodyChecker",
                           "parameters": [ { "name": "text", "value": "d" } ] }
             }
        "responseDescriptor": {
          "code": 200,
          "delay": 0,
          "mimeType": "text/plain",
          "templateName": "notUserResponse",
          "sequenceDescriptorName": "sequenceDescriptorName",
          "responseFormatterSet": [ ... ] 
        }
      }
    ],
    "templates": [
      {
        "name": "notUserResponse",
        "resource": "The Response",
        "type": "text"
      }
    ]
  }
}

It means if the request belongs to a sequence, and a stub response is expected, the formatters will get the right sequence object during the response generation. If no sequenceDescriptorName is given for a responseDescriptor, or when the request does not belong to any sequence, the formatter classes will get a null reference.


Expired sequences

There is a property in wilma.conf.properties file: sequence.cleanup.cron. Wilma uses this cron expression to trigger the sequence cleaning task. This task goes through all sequence objects and checks their timeout values. If a sequence object is expired, this task will destroy it.

It is possible to trigger the sequence cleaning task by manually. To do this you must send a request to http://wilmadomain:wilmahost/config/admin/sequence/cleanup servlet.

In the case of any interaction with the sequence object, - like a new request or a response arrives and it belongs to a specific sequence object, - Wilma updates the timeout value of the sequence.


Information

Wilma provides information about the live sequences. http://wilmadomain:wilmahost/config/public/livesequences servlet gives back a JSON containing the following information.

{"groupedbydescriptors":{"Adescriptor":< countofAdescriptorssequences >, …},
"countofsequences":< sumofallsequences >}

Built-in Sequence Handlers and Sequence Related Condition Checkers

Built-in sequence handler and condition checker classes used for Sequence Handling:

  • SessionIdBasedSequenceHandler - a class that implements SequenceHandler interface, to collect sessions with the help of the SessionIdChecker condition class.
  • SessionIdChecker - a class that implements ConditionEvaluator interface. This condition becomes true if the name attribute of the first parameter of this condition can be found as name of a parameter in the header of the request.

Example configuration:

    "sequenceDescriptors": [
      {
        "name": "session-collector",
        "class": "SessionIdBasedSequenceHandler",
        "conditionDescriptor": { "condition": { 
                                     "class": "SessionIdChecker", 
                                     "parameters": [ {"name": "SESSION-ID", "value": "something_irrelevant" } ] 
                                     } 
                               },
        "parameters": [ {"name": "headerName", "value": "SESSION-ID" } ] 
      }
    ]

In the above config, the SessionIdChecker serves to filter out request which don't have a HTTP header called "SESSION-ID". SessionIdBasedSequenceHandler will group requests into sequences based on the value of the "SESSION-ID" header.


Response generation in case of Sequences

In order to receive the sequences by the response formatter, the stubbed request belongs to its response descriptor has to reference the name of the specific sequence descriptor.

Example:

        "responseDescriptor": {
          "code": 200,
          "delay": 0,
          "mimeType": "text/plain",
          "templateName": "notUserResponse",
          "sequenceDescriptorName": "session-collector"
        }

In the example above, "session-collector" is the name of the sequence that will be passed to the template formatters to format the stub response.

Built-in Sequence handling related response formatters:

  • SequenceAwareXslBasedResponseFormatter
  • SequenceAwareJsonResponseFormatter

Example on using SequenceAwareXslBasedResponseFormatter built-in sequence aware response formatter class:

"templates": [ { "name": template_MagicResponse", 
                 "type": "xmlFile", 
                 "resource": "MagicResponse.xml" } ],
"responseFormatterSets": [ {
    "name": "invoke_MagicResponse",
    "responseFormatterSet": [ {
        "responseFormatter": {
            "class": "SequenceAwareXslBasedResponseFormatter",
            "parameters": [ {"name": "xslFile", "value": "MagicResponse.xsl-ID" },
                            {"name": "type:Important", "value": "url:.*/PancakeLand" } ] 
        }
    } ]
} ]

See further details at Response Formatters page.

Clone this wiki locally