outofcoffee / imposter

Scriptable, multipurpose mock server. Run standalone mock servers, or embed mocks within your tests.
https://imposter.sh
Other
374 stars 61 forks source link

soap issue - Serving mock example - Docker image #630

Open DeveOwn opened 1 month ago

DeveOwn commented 1 month ago

Issue: SOAP Plugin returning mock example instead of the defined response when using shared folder mapping

I am encountering an issue with the Imposter SOAP plugin when mapping a shared folder for multiple plugins. Specifically, when I map a shared directory (e.g., ../Configs:/opt/imposter/config), which contains multiple subdirectories for different plugins, the SOAP plugin returns a mock example response instead of the XML response defined in the corresponding YAML configuration file.

However, when I map the exact folder path to the specific plugin configuration (e.g., ../Configs/soap-plugin:/opt/imposter/config/examples), the SOAP service works correctly and returns the defined XML response as expected. The only difference in behavior appears to be the folder mapping structure, where a shared directory with subdirectories causes the plugin to return a mock example.

I have already enabled recursive scanning of configuration directories using the following environment variable: IMPOSTER_CONFIG_SCAN_RECURSIVE=true Here are the log traces that demonstrate the issue:

2024-09-24 19:59:17 01:59:17 TRACE i.v.e.w.i.RouterImpl - Router: 834069932 accepting request POST http://localhost:8080/pets/ 2024-09-24 19:59:17 01:59:17 TRACE i.v.e.w.RoutingContext - Route matches: RouteState{metadata=null, path='null', name=null, order=1, enabled=true, methods=null, consumes=null, emptyBodyPermittedWithConsumes=false, produces=null, contextHandlers=[io.gatehill.imposter.server.vertxweb.VertxWebServerFactoryImpl$$Lambda$605/0x00007fc1f871faa0@280fb79e], failureHandlers=null, added=true, pattern=null, groups=null, useNormalizedPath=true, namedGroupsInRegex=null, virtualHostPattern=null, pathEndsWithSlash=false, exclusive=false, exactPath=true} 2024-09-24 19:59:17 01:59:17 TRACE i.v.e.w.RoutingContext - Calling the handler 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.s.v.VertxWebServerFactoryImpl - Completed handling request for: null null 2024-09-24 19:59:17 01:59:17 TRACE i.v.e.w.RoutingContext - Route matches: RouteState{metadata=null, path='/pets/', name=null, order=4, enabled=true, methods=[POST], consumes=null, emptyBodyPermittedWithConsumes=false, produces=null, contextHandlers=[io.gatehill.imposter.server.vertxweb.VertxWebServerFactoryImpl$$Lambda$605/0x00007fc1f871faa0@31591c99], failureHandlers=null, added=true, pattern=null, groups=null, useNormalizedPath=true, namedGroupsInRegex=null, virtualHostPattern=null, pathEndsWithSlash=true, exclusive=false, exactPath=true} 2024-09-24 19:59:17 01:59:17 TRACE i.v.e.w.RoutingContext - Calling the handler 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.h.AbstractResourceMatcher - Matched 0 resource configs for POST http://localhost:8080/pets/: [] 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.p.s.SoapResourceMatcher - SOAPAction from content type header: null 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.p.s.SoapResourceMatcher - No SOAPAction found 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.p.s.SoapResourceMatcher - Matched 1 operations in binding SoapBinding based on body root element: getPetByIdRequest: [getPetById] 2024-09-24 19:59:17 01:59:17 TRACE i.g.i.h.AbstractResourceMatcher - No request body config to match for POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.h.AbstractResourceMatcher - Request match evaluation for '[50e90345-69b2-4786-80a7-be97084d64dd] POST http://localhost:8080/pets/' to resource SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/backend/pets/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=af71831d-febf-40e7-8a6c-390f208d15c2), from results: [ResourceMatchResult(description=path, type=NOT_MATCHED, weight=0), ResourceMatchResult(description=SOAP action, type=NO_CONFIG, weight=1), ResourceMatchResult(description=SOAP binding, type=NO_CONFIG, weight=1), ResourceMatchResult(description=SOAP operation, type=EXACT_MATCH, weight=1), ResourceMatchResult(description=request body, type=NO_CONFIG, weight=1), ResourceMatchResult(description=eval, type=NO_CONFIG, weight=1)], outcome: MatchedResource(resource=ResolvedResourceConfig(config=SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/backend/pets/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=af71831d-febf-40e7-8a6c-390f208d15c2), pathParams={}, queryParams={}, formParams={}, requestHeaders={}), matched=false, score=1, exact=false) 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.h.AbstractResourceMatcher - No matching resource config for POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.s.SecurityLifecycleListenerImpl - No security policy found for: POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.SoapResourceMatcher - SOAPAction from content type header: null 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.SoapResourceMatcher - No SOAPAction found 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.SoapResourceMatcher - Matched 1 operations in binding SoapBinding based on body root element: getPetByIdRequest: [getPetById] 2024-09-24 19:59:18 01:59:18 DEBUG i.g.i.p.s.SoapPluginImpl - Matched operation: getPetById in binding: SoapBinding 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.StepService - Prepared 0 step(s) for resource with ID: d1248ab6-d3ef-4c16-b198-e63b053de4ff: SoapPluginConfig(parent=CommonPluginConfig(parent=PluginConfigImpl(parent=AbstractResourceConfig(path=null, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=null, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), plugin=soap, systemConfig=null), basePath=null, corsConfig=null, upstreams=null), wsdlFile=petstore.wsdl, resources=[SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/backend/pets/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=af71831d-febf-40e7-8a6c-390f208d15c2)], isDefaultsFromRootResponse=false, envelope=true) 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.ResponseRoutingServiceImpl - 0 processing steps for request: POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.ResponseRoutingServiceImpl - Using default HTTP 200 response behaviour for request: POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.SoapPluginImpl - Using output schema type: ElementOperationMessage(elementName={urn:com:example:petstore}getPetByIdResponse) 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.ResponseServiceImpl - Sending mock response for POST http://localhost:8080/pets/ with status code 200 2024-09-24 19:59:18 01:59:18 WARN i.g.i.s.ResponseServiceImpl - Response file and data are blank for [50e90345-69b2-4786-80a7-be97084d64dd] POST http://localhost:8080/pets/ 2024-09-24 19:59:18 01:59:18 DEBUG i.g.i.p.s.s.SoapExampleService - Generating response example for operation: getPetById in service: PetService 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.s.SoapExampleService - Generated document response XML: <urn:getPetByIdResponse xmlns:urn="urn:com:example:petstore"> 2024-09-24 19:59:18 <id>3</id> 2024-09-24 19:59:18 <name>string</name> 2024-09-24 19:59:18 </urn:getPetByIdResponse> 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.p.s.s.SoapExampleService - Serving mock example for POST http://localhost:8080/pets/ with status code 200: <?xml version="1.0" encoding="UTF-8"?> 2024-09-24 19:59:18 <env:Envelope xmlns:env="http://www.w3.org/2001/12/soap-envelope"> 2024-09-24 19:59:18 <env:Header/> 2024-09-24 19:59:18 <env:Body> 2024-09-24 19:59:18 <urn:getPetByIdResponse xmlns:urn="urn:com:example:petstore"> 2024-09-24 19:59:18 <id>3</id> 2024-09-24 19:59:18 <name>string</name> 2024-09-24 19:59:18 </urn:getPetByIdResponse> 2024-09-24 19:59:18 </env:Body> 2024-09-24 19:59:18 </env:Envelope> 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.f.DelegatingStoreFactoryImpl - Resolved store driver: store-inmem to class: io.gatehill.imposter.store.inmem.InMemoryStoreFactoryImpl 2024-09-24 19:59:18 01:59:18 TRACE i.g.i.s.v.VertxWebServerFactoryImpl - Completed handling request for: POST /pets/

Logs when using an exact folder path (../Configs/soap-plugin):

2024-09-24 19:57:20 01:57:20 TRACE i.v.e.w.i.RouterImpl - Router: 539620443 accepting request POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.v.e.w.RoutingContext - Route matches: RouteState{metadata=null, path='null', name=null, order=1, enabled=true, methods=null, consumes=null, emptyBodyPermittedWithConsumes=false, produces=null, contextHandlers=[io.gatehill.imposter.server.vertxweb.VertxWebServerFactoryImpl$$Lambda$606/0x00007f072071a000@616041a4], failureHandlers=null, added=true, pattern=null, groups=null, useNormalizedPath=true, namedGroupsInRegex=null, virtualHostPattern=null, pathEndsWithSlash=false, exclusive=false, exactPath=true} 2024-09-24 19:57:20 01:57:20 TRACE i.v.e.w.RoutingContext - Calling the handler 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.v.VertxWebServerFactoryImpl - Completed handling request for: null null 2024-09-24 19:57:20 01:57:20 TRACE i.v.e.w.RoutingContext - Route matches: RouteState{metadata=null, path='/pets/', name=null, order=12, enabled=true, methods=[POST], consumes=null, emptyBodyPermittedWithConsumes=false, produces=null, contextHandlers=[io.gatehill.imposter.server.vertxweb.VertxWebServerFactoryImpl$$Lambda$606/0x00007f072071a000@23b49d3], failureHandlers=null, added=true, pattern=null, groups=null, useNormalizedPath=true, namedGroupsInRegex=null, virtualHostPattern=null, pathEndsWithSlash=true, exclusive=false, exactPath=true} 2024-09-24 19:57:20 01:57:20 TRACE i.v.e.w.RoutingContext - Calling the handler 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.h.AbstractResourceMatcher - Matched 0 resource configs for POST http://localhost:8080/pets/: [] 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - SOAPAction from content type header: null 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - No SOAPAction found 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - Matched 1 operations in binding SoapBinding based on body root element: getPetByIdRequest: [getPetById] 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.h.AbstractResourceMatcher - No request body config to match for POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.h.AbstractResourceMatcher - Request match evaluation for '[3ad2a284-3769-4ce8-a721-96235a11f7e9] POST http://localhost:8080/pets/' to resource SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=a1c19d21-4d30-44cd-9546-5f190ab3c2da), from results: [ResourceMatchResult(description=path, type=EXACT_MATCH, weight=1), ResourceMatchResult(description=SOAP action, type=NO_CONFIG, weight=1), ResourceMatchResult(description=SOAP binding, type=NO_CONFIG, weight=1), ResourceMatchResult(description=SOAP operation, type=EXACT_MATCH, weight=1), ResourceMatchResult(description=request body, type=NO_CONFIG, weight=1), ResourceMatchResult(description=eval, type=NO_CONFIG, weight=1)], outcome: MatchedResource(resource=ResolvedResourceConfig(config=SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=a1c19d21-4d30-44cd-9546-5f190ab3c2da), pathParams={}, queryParams={}, formParams={}, requestHeaders={}), matched=true, score=2, exact=true) 2024-09-24 19:57:20 01:57:20 DEBUG i.g.i.h.AbstractResourceMatcher - Matched resource config for POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.s.SecurityLifecycleListenerImpl - No security policy found for: POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - SOAPAction from content type header: null 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - No SOAPAction found 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapResourceMatcher - Matched 1 operations in binding SoapBinding based on body root element: getPetByIdRequest: [getPetById] 2024-09-24 19:57:20 01:57:20 DEBUG i.g.i.p.s.SoapPluginImpl - Matched operation: getPetById in binding: SoapBinding 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.StepService - Prepared 0 step(s) for resource with ID: a1c19d21-4d30-44cd-9546-5f190ab3c2da: SoapPluginResourceConfig(parent=AbstractResourceConfig(path=/pets/, securityConfig=null, captureConfig=null, responseConfig=ResponseConfig(file=getPetByIdResponse.xml, content=null, dir=null, isTemplate=null, scriptFile=null, statusCode=null, headers=null, performanceDelay=null, failureType=null), continueToNext=null), binding=null, operation=getPetById, soapAction=null, requestBody=null, eval=null, resourceId=a1c19d21-4d30-44cd-9546-5f190ab3c2da) 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.ResponseRoutingServiceImpl - 0 processing steps for request: POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.ResponseRoutingServiceImpl - Using default HTTP 200 response behaviour for request: POST http://localhost:8080/pets/ 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.p.s.SoapPluginImpl - Using output schema type: ElementOperationMessage(elementName={urn:com:example:petstore}getPetByIdResponse) 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.ResponseServiceImpl - Sending mock response for POST http://localhost:8080/pets/ with status code 200 2024-09-24 19:57:20 01:57:20 INFO i.g.i.s.ResponseFileServiceImpl - Serving response file getPetByIdResponse.xml for POST http://localhost:8080/pets/ with status code 200 2024-09-24 19:57:20 01:57:20 TRACE i.g.i.s.v.VertxWebServerFactoryImpl - Completed handling request for: POST /pets/

If I’ve missed any relevant details, or if there are additional steps I should try, please let me know.

outofcoffee commented 4 weeks ago

Hi @DeveOwn, It looks like the path of the resource is being rewritten from /pets/ to /backend/pets/pets/, which would cause the request not to match in the first instance.

Is IMPOSTER_AUTO_BASE_PATH=true? If so, does this issue occur if you set it to false?

Alternatively, is the basePath property set in the config file? If so, does the issue occur if you don't set it?