step’s architecture allows for the dynamic registration of agents. It is designed to handle hundreds of such agents, enabling the execution of keywords at a very high rate. Different types of agents have been released in order to support tight integration with different runtime. For instance, DLL-based keywords can run on the .NET agent, while a node.js project can be executed on step’s node agent.
step’s default routing will guarantee a natural affinity between a keyword’s given type and the agent on which this keyword’s execution will occur. However, users can define arbitrary affinity patterns allowing for further customization. For instance, one may decide to assign a specific set of agents to a group which will work in isolation from the other agents, depending on contextual information provided at runtime.
In this how-to, we will cover the configuration of an agent and how to design groups based on affinity patterns. We will also look at the different options user have at their disposal to design and implement complex keyword routing rules.
All of step’s agents use the same type configuration file - AgentConf.json - which should look more or less like this by default:
You’re probably already familiar with the gridHost parameter, which allows the agent to connect and register against a controller.
The tokenGroups parameter exposes a collection of pools which can be tagged with different key-values (via the properties sub-map). The sub-map called attributes can be used to tag a certain pool with key-values and allow for a distinction between this pool and other pools belonging to the same agent or to other agents from the same technical type. The sub-map called properties allows to set specific property values which will only be visible in the context of a token originating from this pool. This means that keywords may “see” different property values depending on which token they end up being executed on.
The capacity parameter decides how many “tokens” (i.e keyword execution slots) will be made available in the corresponding pool upon starting the agent. Make sure not to enable more tokens than the underlying host is capable of servicing based on its allocated infrastructure resources (CPU, Mem, I/O..).
Lastly, a separate properties map allows the declaration of global agent properties made accessible to keywords and which will look the same to every keyword executing on the agent, assuming the property is not overridden within the property map of the pool.
Token Pool attributes
In the sample file provided above, the attribute “myAffinityCriterion1” is set on the only pool which has been configured and the value “myAffinityValue1” has been assigned to it. This means that keywords may or may not be routed to this token pool depending on selection criteria which will be evaluated at runtime.
These criteria can be decided either by setting the corresponding variable in the plan, in the Routing map of a CallKeyword instance or of a Session instance, or via the route_to_XYZ variable, which can itself be set as a parameter and be manipulated dynamically.
Token Pool properties
In the sample file provided above, the dummy property “myProp1” is set on the only pool which has been configured and it takes the value “myValue1”. This means that keywords running in the context of tokens belonging to this pool will see this value when accessing the property:
Let’s assume in the following examples that we’ve installed and started two agent pools (which may or may not be running on the same agent and/or host) using the attribute “myAffinityCriterion1” as a distinguishing criterion. Values “myAffinityValue1” and “myAffinityValue2” have been assigned respectively to token pools 1 & 2.
Explicit keyword routing
Both the CallKeyword (i.e the underlying object created when using a keyword in a plan) and Session artefacts showcase a section called “Keyword routing”. This section exposes a map of desired attributes which will be matched at runtime against the actual attributes of the tokens available for selection.
If we set our criterion “myAffinityCriterion1” to the value “myAffinityValue2”, then this keyword’s execution will only be able to take place on the corresponding pool and agent:
Upon execution, the details pane confirms this. If you look at the url of the agent taking care of the execution, you will see that it is the url of agent 2, as expected.
The same result can be achieved using a the reserved variable routeto. This variable can be set, for instance, as a central parameter, and overridden in a plan where necessary.
After removing the explicit routing key and value from our keyword call, we’ll apply a similar constraint with the routeto variable by appending the criterion to its name and setting the value as a parameter value.
Again, execution will take place on agent 2.
Let’s now override this value from within the plan by using a Set artefact from within the plan, and just before the keyword is effectively called.