diff --git a/.docker/wiremock/mappings/soap-fault.json b/.docker/wiremock/mappings/soap-fault.json
new file mode 100644
index 0000000..e7a6091
--- /dev/null
+++ b/.docker/wiremock/mappings/soap-fault.json
@@ -0,0 +1,19 @@
+{
+ "name": "SOAP (non-WSDL, urn:demo): Fail returns a SOAP fault",
+ "request": {
+ "method": "POST",
+ "urlPath": "/soap",
+ "headers": {
+ "SOAPAction": {
+ "contains": "#Fail"
+ }
+ }
+ },
+ "response": {
+ "status": 500,
+ "headers": {
+ "Content-Type": "text/xml; charset=utf-8"
+ },
+ "body": "SOAP-ENV:ServerBook service unavailable"
+ }
+}
diff --git a/.docker/wiremock/mappings/soap-get-book.json b/.docker/wiremock/mappings/soap-get-book.json
new file mode 100644
index 0000000..dd54d43
--- /dev/null
+++ b/.docker/wiremock/mappings/soap-get-book.json
@@ -0,0 +1,19 @@
+{
+ "name": "SOAP (non-WSDL, urn:demo): GetBook returns a title",
+ "request": {
+ "method": "POST",
+ "urlPath": "/soap",
+ "headers": {
+ "SOAPAction": {
+ "contains": "#GetBook"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "text/xml; charset=utf-8"
+ },
+ "body": "It"
+ }
+}
diff --git a/.docker/wiremock/mappings/soap-is-available.json b/.docker/wiremock/mappings/soap-is-available.json
new file mode 100644
index 0000000..358b002
--- /dev/null
+++ b/.docker/wiremock/mappings/soap-is-available.json
@@ -0,0 +1,19 @@
+{
+ "name": "SOAP (non-WSDL, urn:demo): IsAvailable legitimately returns false",
+ "request": {
+ "method": "POST",
+ "urlPath": "/soap",
+ "headers": {
+ "SOAPAction": {
+ "contains": "#IsAvailable"
+ }
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "text/xml; charset=utf-8"
+ },
+ "body": "false"
+ }
+}
diff --git a/config/packages/process/demo.soap.client_headers.yaml b/config/packages/process/demo.soap.client_headers.yaml
new file mode 100644
index 0000000..bf3ec11
--- /dev/null
+++ b/config/packages/process/demo.soap.client_headers.yaml
@@ -0,0 +1,56 @@
+clever_age_process:
+ configurations:
+ demo.soap.client_headers:
+ description: >
+ RequestTask without soap_call_headers on a client whose headers are set by `calls`
+ (cleverage/soap-process-bundle#29): the ClientToken header of the client definition must be sent
+ (the WireMock request journal must count 1 request with it)
+ help: >
+ Ex: bin/console cleverage:process:execute demo.soap.client_headers
+ tasks:
+ reset:
+ service: '@CleverAge\RestProcessBundle\Task\RequestTask'
+ description: Reset the WireMock request journal
+ options:
+ client: wiremock_admin
+ url: '/requests'
+ method: 'DELETE'
+ outputs: [ input ]
+
+ input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ options:
+ output:
+ id: 1
+ outputs: [ request ]
+
+ request:
+ service: '@CleverAge\SoapProcessBundle\Task\RequestTask'
+ options:
+ client: wiremock
+ method: 'GetBook'
+ outputs: [ no_input ]
+
+ no_input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ description: The next request does not take the previous output as input
+ options:
+ output: { }
+ outputs: [ count ]
+
+ count:
+ service: '@CleverAge\RestProcessBundle\Task\RequestTask'
+ description: Count the SOAP requests sent with the ClientToken header, must output {"count":1}
+ options:
+ client: wiremock_admin
+ url: '/requests/count'
+ method: 'POST'
+ data:
+ method: 'POST'
+ url: '/soap'
+ bodyPatterns:
+ - contains: 'ClientToken'
+ outputs: [ debug ]
+
+ debug:
+ service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask'
diff --git a/config/packages/process/demo.soap.false_result.yaml b/config/packages/process/demo.soap.false_result.yaml
new file mode 100644
index 0000000..bb7d00b
--- /dev/null
+++ b/config/packages/process/demo.soap.false_result.yaml
@@ -0,0 +1,25 @@
+clever_age_process:
+ configurations:
+ demo.soap.false_result:
+ description: >
+ SOAP method legitimately returning false (cleverage/soap-process-bundle#31): false must be output, the
+ call must not be handled as failed
+ help: >
+ Ex: bin/console cleverage:process:execute demo.soap.false_result
+ tasks:
+ input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ options:
+ output:
+ id: 1
+ outputs: [ request ]
+
+ request:
+ service: '@CleverAge\SoapProcessBundle\Task\RequestTask'
+ options:
+ client: wiremock
+ method: 'IsAvailable'
+ outputs: [ debug ]
+
+ debug:
+ service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask'
diff --git a/config/packages/process/demo.soap.fault_without_exceptions.yaml b/config/packages/process/demo.soap.fault_without_exceptions.yaml
new file mode 100644
index 0000000..4ae96d4
--- /dev/null
+++ b/config/packages/process/demo.soap.fault_without_exceptions.yaml
@@ -0,0 +1,18 @@
+clever_age_process:
+ configurations:
+ demo.soap.fault_without_exceptions:
+ description: >
+ SOAP fault on a client with the exceptions: false option (cleverage/soap-process-bundle#32): the
+ call must fail, the SoapFault must not be output as a result
+ help: >
+ Ex: bin/console cleverage:process:execute demo.soap.fault_without_exceptions
+ tasks:
+ request:
+ service: '@CleverAge\SoapProcessBundle\Task\RequestTask'
+ options:
+ client: wiremock_no_exceptions
+ method: 'Fail'
+ outputs: [ debug ]
+
+ debug:
+ service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask'
diff --git a/config/packages/process/demo.soap.headers_leak.yaml b/config/packages/process/demo.soap.headers_leak.yaml
new file mode 100644
index 0000000..3c6e8c8
--- /dev/null
+++ b/config/packages/process/demo.soap.headers_leak.yaml
@@ -0,0 +1,76 @@
+clever_age_process:
+ configurations:
+ demo.soap.headers_leak:
+ description: >
+ RequestTask with soap_call_headers, then the soap_request transformer on the same client
+ (cleverage/soap-process-bundle#30): the TaskToken header must only be sent by the task (the WireMock
+ request journal must count 1 request with it)
+ help: >
+ Ex: bin/console cleverage:process:execute demo.soap.headers_leak
+ tasks:
+ reset:
+ service: '@CleverAge\RestProcessBundle\Task\RequestTask'
+ description: Reset the WireMock request journal
+ options:
+ client: wiremock_admin
+ url: '/requests'
+ method: 'DELETE'
+ outputs: [ input ]
+
+ input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ options:
+ output:
+ id: 1
+ outputs: [ request ]
+
+ request:
+ service: '@CleverAge\SoapProcessBundle\Task\RequestTask'
+ options:
+ client: wiremock
+ method: 'GetBook'
+ soap_call_headers:
+ TaskToken:
+ namespace: 'urn:demo'
+ data: 'from-the-task'
+ outputs: [ transformer_input ]
+
+ transformer_input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ options:
+ output:
+ id: 2
+ outputs: [ transformer ]
+
+ transformer:
+ service: '@CleverAge\ProcessBundle\Task\TransformerTask'
+ options:
+ transformers:
+ soap_request:
+ client: wiremock
+ method: 'GetBook'
+ outputs: [ no_input ]
+
+ no_input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ description: The next request does not take the previous output as input
+ options:
+ output: { }
+ outputs: [ count ]
+
+ count:
+ service: '@CleverAge\RestProcessBundle\Task\RequestTask'
+ description: Count the SOAP requests sent with the TaskToken header, must output {"count":1}
+ options:
+ client: wiremock_admin
+ url: '/requests/count'
+ method: 'POST'
+ data:
+ method: 'POST'
+ url: '/soap'
+ bodyPatterns:
+ - contains: 'TaskToken'
+ outputs: [ debug ]
+
+ debug:
+ service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask'
diff --git a/config/packages/process/demo.soap.invalid_input.yaml b/config/packages/process/demo.soap.invalid_input.yaml
new file mode 100644
index 0000000..b8eb82c
--- /dev/null
+++ b/config/packages/process/demo.soap.invalid_input.yaml
@@ -0,0 +1,24 @@
+clever_age_process:
+ configurations:
+ demo.soap.invalid_input:
+ description: >
+ RequestTask receiving a string input (cleverage/soap-process-bundle#33): the task only accepts an
+ array or empty input, it must fail with a clear message
+ help: >
+ Ex: bin/console cleverage:process:execute demo.soap.invalid_input
+ tasks:
+ input:
+ service: '@CleverAge\ProcessBundle\Task\ConstantOutputTask'
+ options:
+ output: 'GetBook'
+ outputs: [ request ]
+
+ request:
+ service: '@CleverAge\SoapProcessBundle\Task\RequestTask'
+ options:
+ client: wiremock
+ method: 'GetBook'
+ outputs: [ debug ]
+
+ debug:
+ service: '@CleverAge\ProcessBundle\Task\Debug\DebugTask'
diff --git a/config/services.yaml b/config/services.yaml
index 8b1d585..af9b800 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -42,8 +42,7 @@ services:
$options:
trace: true
exceptions: true
- calls:
- - [ setSoapOptions, [ { features: SOAP_SINGLE_ELEMENT_ARRAYS} ] ]
+ features: !php/const SOAP_SINGLE_ELEMENT_ARRAYS
tags:
- { name: cleverage.soap.client }
@@ -71,6 +70,34 @@ services:
tags:
- { name: cleverage.rest.client }
+ # SOAP clients (non-WSDL mode, urn:demo) on the WireMock service (stubs .docker/wiremock/mappings/soap-*.json).
+ # The headers set by `calls` are sent with every call (cleverage/soap-process-bundle#29); the second client
+ # does not throw on SOAP faults (exceptions: false, cleverage/soap-process-bundle#32).
+ app.cleverage_soap_process.client.wiremock:
+ class: CleverAge\SoapProcessBundle\Client\Client
+ bind:
+ $code: 'wiremock'
+ $wsdl: null
+ $options:
+ location: '%env(string:WIREMOCK_URL)%/soap'
+ uri: 'urn:demo'
+ calls:
+ - [ setSoapHeaders, [ [ !service { class: SoapHeader, arguments: [ 'urn:demo', 'ClientToken', 'from-the-client-definition' ] } ] ] ]
+ tags:
+ - { name: cleverage.soap.client }
+
+ app.cleverage_soap_process.client.wiremock_no_exceptions:
+ class: CleverAge\SoapProcessBundle\Client\Client
+ bind:
+ $code: 'wiremock_no_exceptions'
+ $wsdl: null
+ $options:
+ location: '%env(string:WIREMOCK_URL)%/soap'
+ uri: 'urn:demo'
+ exceptions: false
+ tags:
+ - { name: cleverage.soap.client }
+
# REST client on an unresolvable host (.invalid TLD): every request fails with a transport error.
# Used by demo.rest.transport_error (cleverage/rest-process-bundle#36).
app.cleverage_rest_process.client.unreachable:
diff --git a/docs/wiremock.md b/docs/wiremock.md
index e349bd6..c836d98 100644
--- a/docs/wiremock.md
+++ b/docs/wiremock.md
@@ -33,6 +33,18 @@ cases (status codes, transport errors...) can be reproduced at will.
Run them with `bin/console cleverage:process:execute ` (`make bash` first).
+### Mocking a SOAP service
+
+WireMock also mocks SOAP services: the `soap-*.json` stubs answer SOAP envelopes on `/soap`, matched on the
+`SOAPAction` header (`urn:demo#` in non-WSDL mode). The `wiremock` SOAP client (`config/services.yaml`) uses
+the non-WSDL mode (`location` / `uri` options), and sets a `ClientToken` header with `calls: [setSoapHeaders, ...]`;
+`wiremock_no_exceptions` uses the `exceptions: false` option.
+
+The `demo.soap.client_headers` and `demo.soap.headers_leak` processes check the SOAP headers actually sent, by
+counting the matching requests with the admin API (`POST /__admin/requests/count` with a `bodyPatterns` criterion);
+`demo.soap.false_result` and `demo.soap.fault_without_exceptions` use the `IsAvailable` (returns `false`) and `Fail`
+(SOAP fault) mocked methods.
+
### Adding a stub
1. Call the API once and look at the unmatched request: `curl http://localhost:8089/__admin/requests/unmatched`.