<!-- Generated from https://trafficparrot.com/documentation/5.65.x/virtual_services.html by scripts/generate-md-mirrors.sh. Do not edit: edit the .html and regenerate. -->

# Virtual Services

<a id="virtual-serv-intro"></a>
## Virtual Services

Traffic Parrot provides two powerful features for managing test environments:

- **Virtual Services (Scenarios)** - Create isolated test environments with separate mappings and configurations. Each virtual service can optionally run on its own dedicated HTTP/HTTPS ports, allowing multiple services to run simultaneously.
- **Composite Scenarios** - Combine mappings from multiple virtual services into a single active scenario. This enables teams to share and merge their test data while maintaining separate scenario management.

Virtual services help organize your test data by project, team, or environment, while composite scenarios provide flexibility in combining these isolated test sets when needed.

<a id="supported-protocols"></a>
## Supported protocols

Currently the following protocols fully support the virtual services feature:

- HTTP
- HTTPS
- Native IBM® MQ
- JMS

Limited support is provided for the following protocols, as per the existing [scenarios feature](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios) documentation:

- gRPC
- Files

<a id="architecture"></a>
## Architecture

- Each Traffic Parrot server can host one or more virtual services
- Each virtual service has a separate configuration directory on the filesystem, including:
  - Separate request to response mappings
  - Separate [virtual service properties file](#virtual-service-properties)
- HTTP virtual services can be run on multiple ports
- MQ virtual services can connect to multiple queue managers
- JMS virtual services can connect to multiple brokers

![Traffic Parrot Virtual Services Directories Architecture Diagram](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/virtual-services-directories.png)

![Traffic Parrot Virtual Services Multiple HTTP Ports Architecture Diagram](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/virtual-services-http-ports.png)

![Traffic Parrot Virtual Services Multiple Queue Managers Ports Architecture Diagram](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/virtual-services-ibm-queue-managers.png)

![Traffic Parrot Virtual Services Home](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/virtual-services-home.png)

<a id="manage"></a>
## Managing Virtual Services

The virtual services can be managed using the Virtual Services UI page:

![Traffic Parrot Virtual Services List](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/virtual-services-list.png)

<a id="manage-add"></a>
##### Add Virtual Service

To add a virtual service, click the new virtual service button:

![Traffic Parrot New Virtual Service Button](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/new-virtual-service-button.png)

Which will show a create dialog:

![Traffic Parrot New Virtual Service Dialog](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/new-virtual-service-modal.png)

Click the submit button to create the virtual service. If a valid free HTTP/HTTPS port is specified, then the virtual service will be accessible on the ports specified.

<a id="manage-edit"></a>
##### Edit Virtual Service

To edit a virtual service, click the edit virtual service button for an existing virtual service in the list:

![Traffic Parrot Edit Virtual Service Button](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/edit-virtual-service-button.png)

![Traffic Parrot Edit Virtual Service Dialog](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/edit-virtual-service-modal.png)

Click the submit button to edit the virtual service. If a valid free HTTP/HTTPS port is specified, then the virtual service will be accessible on those ports. The service will no longer be accessible on the old ports.

<a id="manage-delete"></a>
##### Delete Virtual Service

To delete a virtual service, click the delete virtual service button for an existing virtual service in the list:

![Traffic Parrot Delete Virtual Service Button](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/delete-virtual-service-button.png)

![Traffic Parrot Delete Virtual Service Dialog](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/delete-virtual-service-modal.png)

Click the delete button to delete the virtual service. The service will no longer be accessible on the old port. The deleted virtual service mappings will be backed up in the `deleted-scenarios` directory.

<a id="manage-select"></a>
##### Select Virtual Service

To select a virtual service, click on the name of the virtual service in the dropdown at the top of the page. This can be accessed from any page.

![Traffic Parrot Select Virtual Service](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/select-virtual-service.png)

Once selected, the following will happen:

- The default HTTP virtual service port of 8081 serves the selected virtual service over HTTP
- The default HTTPS virtual service port of 8082 serves the selected virtual service over HTTPS
- Selecting a virtual service is a server-wide change, not a per-user view: the default ports answer with the selected virtual service for every client that sends requests to them, so the traffic other people send to those ports changes too (a virtual service with its own ports keeps answering on them)
- The custom HTTP/HTTPS ports assigned to each virtual service remain active regardless of the currently selected virtual service
- The Add/Edit/Record/Replay pages for all protocols now impact the currently selected virtual service

<a id="virtual-service-properties"></a>
##### Virtual Service Properties

Each virtual service has a `service.properties` file that is used to specify configuration such as custom HTTPS certificates and MQ startup settings:

| Property name | Description | Example usage |
| --- | --- | --- |
| http.port | The HTTP port for the virtual service | `http.port=9017` |
| https.port | The HTTPS port for the virtual service | `https.port=9018` |
| https.key.store.path | Path to the HTTPS key store to use, relative to the virtual service directory | `https.key.store.path=certs/server.jks` |
| https.key.store.password | The password for the HTTPS key store | `https.key.store.password=password` |
| https.key.manager.password | The password for the HTTPS key store manager | `https.key.manager.password=password` |
| https.key.store.type | The type of key store used, for example JKS or PKCS12 | `https.key.store.type=JKS` |
| https.need.client.auth | Whether client authentication is required. Set to true or false. | `https.need.client.auth=true` |
| https.trust.store.path | Path to the HTTPS trust store to use, relative to the virtual service directory | `https.trust.store.path=certs/servertrust.jks` |
| https.trust.store.password | The password for the HTTPS trust store | `https.trust.store.password=password` |
| https.trust.store.type | The type of trust store used, for example JKS or PKCS12 | `https.trust.store.type=JKS` |
| ibm.mq.queue.replay.on.startup | When set to true, replay mode will be enabled for this virtual service `ibm-mq-mappings` on startup | `ibm.mq.queue.replay.on.startup=true` |
| ibm.mq.queue.replay.request.queue.manager | The name of the queue manager to connect to consume request messages, as specified in `ibm-mq-connections.json` | `ibm.mq.queue.replay.request.queue.manager=REQ.QM` |
| ibm.mq.queue.replay.response.queue.manager | The name of the queue manager to connect to produce response messages, as specified in `ibm-mq-connections.json` | `ibm.mq.queue.replay.response.queue.manager=RSP.QM` |
| jms.queue.replay.on.startup | When set to true, replay mode will be enabled for this virtual service `jms-mappings` on startup | `jms.queue.replay.on.startup=true` |
| jms.queue.replay.request.connection.id | The id of the connection to use to consume request messages, as specified in `jms-connections.json` | `jms.queue.replay.request.connection.id=1` |
| jms.queue.replay.response.connection.id | The id of the connection to use to produce response messages, as specified in `jms-connections.json` | `jms.queue.replay.response.connection.id=2` |

<a id="vs-configuration"></a>
## Virtual Service Configuration

<a id="vs-configuration-http"></a>
### HTTP

To configure a HTTP virtual service you should:

1. (optional) Follow the instructions to [add a new virtual service](#manage-add) and specify a HTTP port
2. Follow the instructions to [select a virtual service](#manage-select)
3. Use the HTTP UI to [Add/Edit mappings](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-http-mappings)

<a id="vs-configuration-https"></a>
### HTTPS

To configure a HTTPS virtual service you should:

1. Follow the instructions to [configure a HTTP virtual service](#vs-configuration-http) and specify a HTTPS port
2. (optional) Configure HTTPS configuration in the [scenarios/ServiceName/service.properties](#virtual-service-properties) file:
   - `https.key.store.path=certs/server.jks`
   - `https.key.store.password=password`
   - `https.key.manager.password=password`
   - `https.key.store.type=JKS`
   - `https.need.client.auth=true`
   - `https.trust.store.path=certs/servertrust.jks`
   - `https.trust.store.password=password`
   - `https.trust.store.type=JKS`

<a id="vs-configuration-native-ibm-mq"></a>
### Native IBM® MQ

To configure a Native IBM® MQ virtual service you should:

1. Configure the [required IBM® MQ JARs](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#ibm-mq-libs) (only needs to be done once per Traffic Parrot instance)
2. (optional) Follow the instructions to [add a new virtual service](#manage-add)
3. Follow the instructions to [select a virtual service](#manage-select)
4. Configure the [scenarios/ServiceName/ibm-mq-connections.json](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#define-connections) file
5. Use the Native IBM® MQ UI to [Add/Edit mappings](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#edit-mq) and [turn on replay mode](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#replaying-mq-queues-external)
6. (optional) Configure Native IBM® MQ startup configuration in the [scenarios/ServiceName/service.properties](#virtual-service-properties) file:
   - `ibm.mq.queue.replay.on.startup=true`
   - `ibm.mq.queue.replay.request.queue.manager=REQ.QM`
   - `ibm.mq.queue.replay.response.queue.manager=RSP.QM`

<a id="vs-configuration-jms"></a>
### JMS

To configure a JMS virtual service you should:

1. (optional) Configure the [required IBM® MQ JARs](https://trafficparrot.com/documentation/5.65.x/jms.html#ibm-mq-libs) (only needs to be done once per Traffic Parrot instance and if using IBM® MQ as your JMS connection type)
2. (optional) Follow the instructions to [add a new virtual service](#manage-add)
3. Follow the instructions to [select a virtual service](#manage-select)
4. Configure the [scenarios/ServiceName/jms-connections.json](https://trafficparrot.com/documentation/5.65.x/jms.html#define-jms-connections) file
5. Use the JMS UI to [Add/Edit mappings](https://trafficparrot.com/documentation/5.65.x/jms.html#edit-jms) and [turn on replay mode](https://trafficparrot.com/documentation/5.65.x/jms.html#replaying-jms-queues-external)
6. (optional) Configure JMS startup configuration in the [scenarios/ServiceName/service.properties](#virtual-service-properties) file:
   - `jms.queue.replay.on.startup=true`
   - `jms.queue.replay.request.connection.id=1`
   - `jms.queue.replay.response.connection.id=2`

<a id="vs-configuration-jms-example"></a>
### JMS example: two queue managers, one virtual service each

One Traffic Parrot can mock JMS request and reply for several test environments at once, each environment on its own IBM® MQ queue manager, by giving each environment its own virtual service. For two environments the layout is:

```
scenarios/
  TestEnvironment1/
    service.properties
    jms-connections.json
    jms-mappings/
      hello.json
  TestEnvironment2/
    service.properties
    jms-connections.json
    jms-mappings/
      hello.json
```

`scenarios/TestEnvironment1/service.properties` starts the service when Traffic Parrot starts and names, by `connectionId`, the connection in this service's own `jms-connections.json` that it consumes requests from and replies on:

```
jms.queue.replay.on.startup=true
jms.queue.replay.request.connection.id=1
jms.queue.replay.response.connection.id=1
```

`scenarios/TestEnvironment1/jms-connections.json` defines that connection, the first environment's queue manager:

```
[
  {
    "connectionId": "1",
    "connectionName": "Test environment 1 queue manager",
    "connectionData": {
      "jmsProvider": "IBM_MQ_9",
      "hostname": "qm1.example.com",
      "port": 1414,
      "queueManager": "QM1",
      "channel": "DEV.APP.SVRCONN",
      "username": "app",
      "password": "passw0rd",
      "useMQCSPAuthenticationMode": true,
      "copyRequestMessageIdToResponseMessageId": false
    }
  }
]
```

`scenarios/TestEnvironment1/jms-mappings/hello.json` is an ordinary [JMS mapping](https://trafficparrot.com/documentation/5.65.x/jms.html#edit-jms-mapping-json), answering a request on `DEV.QUEUE.1` whose body is `hello` with a reply on `DEV.QUEUE.2`:

```
{
  "request" : {
    "destination" : {
      "name" : "DEV.QUEUE.1",
      "type" : "QUEUE"
    },
    "bodyMatcher" : {
      "equalTo" : "hello"
    }
  },
  "response" : {
    "destination" : {
      "name" : "DEV.QUEUE.2",
      "type" : "QUEUE"
    },
    "text" : "Reply from TestEnvironment1 on QM1"
  }
}
```

`scenarios/TestEnvironment2/` has the same three files, with its `jms-connections.json` pointing at the second queue manager (`QM2` on its own host) and its mapping replying `Reply from TestEnvironment2 on QM2`. Both services start with Traffic Parrot, and each answers only the requests that arrive on its own queue manager, so the two environments use the same queue names and still get their own replies.

To add an environment later without a restart, copy its folder into `scenarios/`, [select it](#manage-select) in the virtual service dropdown and [start replay](https://trafficparrot.com/documentation/5.65.x/jms.html#replaying-jms-queues-external) on the JMS page; the services already running are not affected.

Every service set to start with Traffic Parrot must be able to reach its queue manager at that moment. If one cannot, Traffic Parrot logs `Problem starting JMS virtual service '<name>'` and `Could not start server`, and stops, whichever environment's queue manager it is. So start Traffic Parrot once every environment's queue manager is up, or leave `jms.queue.replay.on.startup` out of that environment's `service.properties` and start its replay from the UI when its queue manager is up.

A JMS connection to IBM® MQ has no TLS settings. For an environment whose queue manager is reached over a TLS channel, use a [native IBM® MQ virtual service](#vs-configuration-native-ibm-mq) instead: its connection takes a [cipher suite and certificates](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#ssl-tls-configuration), and it serves JMS applications too, with each reply's correlation id set to the request's message id.

All the services run in one JVM, so raise `-Xmx` in [`jvm.args`](https://trafficparrot.com/documentation/5.65.x/user_guide.html#jvm-arguments) as you add services and mappings.

<a id="composite-scenarios"></a>
## Composite Scenarios

The Composite scenario feature allows you to combine mappings from multiple scenarios into a single active scenario. This is useful for testing complex environments where different teams maintain separate scenario sets that need to work together.

### Accessing Composite Scenarios

To access the Composite scenario management interface:

1. Navigate to the **Virtual Services** page from the main navigation bar
2. Click the **"Manage Composite Scenario"** button (with grid icon) at the top of the page
3. Alternatively, if the Composite scenario is listed in the virtual services table, click the **"Configure"** button next to it

The Composite scenario also appears in the scenario dropdown selector with a link emoji (🔗) indicator. Selecting it from the dropdown activates the Composite scenario rather than opening the management interface.

### Managing Composite Scenarios

![Composite scenario management interface](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/composite-scenario.png)

#### Adding Scenarios to Composite

To add a scenario to the composite:

1. Navigate to the Composite Scenario page
2. In the "Available Scenarios" list, click the "+ Add" button next to the scenario you want to include

#### Removing Scenarios from Composite

To remove a scenario from the composite:

1. Navigate to the Composite Scenario page
2. Click the "Remove" button next to the scenario you want to remove

#### Clearing All Scenarios

Click "Clear All" to remove all scenarios from the composite at once.

### How Composite Scenarios Work

When the Composite scenario is active:

- Mappings from all included scenarios are combined and available
- If two scenarios contribute the same file (a conflict), one version is chosen as the winner; see [Conflict Resolution](#composite-conflict-resolution) below
- The composite scenario uses the default HTTP/HTTPS ports
- Changes made while the Composite scenario is active are saved to the Composite scenario directory

> #### Note
>
> The Composite scenario is HTTP-only and does not support combining non-HTTP protocol mappings.

<a id="composite-conflict-resolution"></a>
### Conflict Resolution

When two scenarios contribute a file with the same relative path (for example `mappings/get-user.json` in both scenarios), the Composite page lists the conflict together with each contributing scenario, the file size, and the last-modified timestamp. This lets you see at a glance which scenarios disagree on which files.

![Composite page listing a conflict between two scenarios, with a 'Default winner' badge on one contributor and a 'Use this version' button on the other](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/composite-conflicts/01-conflict-default-winner.png)

Click **Preview** next to a conflict to inspect each contributor's version of the file. Text files (JSON mappings, response bodies, and similar) render inline so you can compare them side by side. Binary files render as a stub that shows the size and a SHA-256 hash for each version, so you can tell whether the two versions differ without trying to render arbitrary bytes. Files larger than 1 MB are not rendered; the preview shows the size and prompts you to inspect the source scenario directly.

![Preview modal showing two contributors' versions of a conflicting JSON mapping file side by side](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/composite-conflicts/03-preview-modal.png)

#### Picking a winner

Each contributor in a conflict row carries one of three indicators:

- **Default winner · `<scenarioId>`**: no explicit choice has been made; this contributor wins because it was the last scenario added to the composite (process-order). This matches the historical behaviour of composite scenarios.
- **Your choice · `<scenarioId>`**: you have explicitly picked this contributor as the winner. The choice is persisted in the composite metadata and survives reloads, restarts, and adding or removing unrelated scenarios.
- **Use this version** button: click to make this contributor the explicit winner. The composite is rebuilt on disk so that replay immediately uses the chosen file. The contributor's badge then changes to *Your choice*.

To revert an explicit choice, click **Clear choice** next to the currently chosen contributor. The composite falls back to the *Default winner* (process-order) for that file.

![Composite page after explicitly choosing a winner: the chosen contributor shows a green 'Your choice' badge with a 'Clear choice' link, and the other contributor's 'Use this version' button has moved to it](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/composite-conflicts/02-explicit-choice-applied.png)

#### Orphaned resolutions

If a scenario that owns an explicit conflict choice is later removed from the composite, the choice can no longer be honoured. The next time the Composite page loads, the orphaned resolution is dropped automatically and a one-time warning banner is shown for each affected file, indicating which path and which scenario reference were dropped. The file then reverts to the default winner.

![Composite page showing the warning banner that appears once after an orphaned conflict resolution is dropped, naming the file path and the removed scenario](https://trafficparrot.com/documentation/5.65.x/img/virtual-services/composite-conflicts/04-orphan-banner.png)

> #### Tip
>
> Conflict choices are keyed by the file's path relative to the composite root, so resolving a conflict at `mappings/get-user.json` does not affect a separate conflict at `mappings/v2/get-user.json`. Each path is resolved independently.

<a id="composite-api-endpoints"></a>
### API Endpoints

The following REST API endpoints are available for managing composite scenarios:

| Method | Endpoint | Description |
| --- | --- | --- |
| `GET` | `/api/scenarios/http/composite` | Get composite scenario status and active scenarios |
| `POST` | `/api/scenarios/http/composite/add?scenario={name}` | Add a scenario to the composite |
| `POST` | `/api/scenarios/http/composite/remove?scenario={name}` | Remove a scenario from the composite |
| `POST` | `/api/scenarios/http/composite/clear` | Clear all scenarios from the composite |

<a id="limitations"></a>
## Limitations

- The UI acts on one virtual service at a time, the one selected in the header dropdown: the mapping lists and editors and the record and replay pages all show and change that service only
- The UI does not support editing the following configuration, which must be configured directly using the file system and a text editor:
  - `scenarios/ServiceName/service.properties`
  - `scenarios/ServiceName/data`
  - `scenarios/ServiceName/ibm-mq-connections.json`
  - `scenarios/ServiceName/jms-connections.json`
  - `scenarios/ServiceName/database-connections.json`
- Live changes to virtual services names and ports are only picked up if the changes are made via the UI (changes directly to the filesystem of a running instance are not picked up dynamically)
- Only one Files/gRPC virtual service can be set to record or replay mode at a time
- Switching virtual service while replay mode is active for Files is not supported and replay must be stopped before switching
- A JMS or native IBM® MQ virtual service set to start replay when Traffic Parrot starts must be able to reach its queue manager at that moment: if any cannot, Traffic Parrot logs `Could not start server` and stops, so start it once every environment's queue manager is up, or start that service's replay from the UI later instead (see the [JMS example](#vs-configuration-jms-example))
- A JMS connection to IBM® MQ has no TLS settings; for a queue manager reached over a TLS channel use a [native IBM® MQ virtual service](#vs-configuration-native-ibm-mq), which takes a cipher suite and certificates and serves JMS applications too
