outofcoffee / imposter Goto Github PK
View Code? Open in Web Editor NEWScriptable, multipurpose mock server. Run standalone mock servers, or embed mocks within your tests.
Home Page: https://imposter.sh
License: Other
Scriptable, multipurpose mock server. Run standalone mock servers, or embed mocks within your tests.
Home Page: https://imposter.sh
License: Other
Is it possible browse the REST requests that have been made to/from Imposter? (via an endpoint)
Only GET requests seem to work with the Rest Plugin. Is it possible to extend it to include POST, PUT & DELETE ?
Hello!
I have a swagger spec that, in-part, looks like:
responses:
Team:
description: success
schema:
$ref: '#/definitions/Team'
examples:
application/json:
id: 10
name: Engineering
The JSON schema that is produced looks like:
"Team": {
"description": "success",
"examples": {
"application/json": {
"id": 10,
"name": "Engineering"
}
},
"schema": {
"$ref": "#/definitions/Team"
}
},
If I hit the imposter API endpoint configured as such:
{
"plugin": "com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl",
"specFile": "apiv2.json",
}
I'm hoping to see the example returned. What I get is:
{id=10, name=Engineering}
which isn't valid JSON.
Looking at curl:
~ $ curl -v -H "Accept: application/json" http://127.0.0.1:8443/api/v2/teams/10
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8443 (#0)
> GET /api/v2/teams/10 HTTP/1.1
> Host: 127.0.0.1:8443
> User-Agent: curl/7.49.1
> Accept: application/json
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 19
<
* Connection #0 to host 127.0.0.1 left intact
Imposter claims that this is JSON.
Watching debug output:
17:10:28.177 [vert.x-worker-thread-7] DEBUG com.gatehill.imposter.service.ResponseServiceImpl - Using default response behaviour for request: http://127.0.0.1:8443/api/v2/teams/10
17:10:28.179 [vert.x-worker-thread-7] DEBUG com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl - Exact example match found (application/json) from specification
17:10:28.179 [vert.x-worker-thread-7] INFO com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl - Serving mock example for URI http://127.0.0.1:8443/api/v2/teams/10 and status code 200 (response body 19 bytes)
It looks like the example is returned, but not as encoded JSON, but as a string representation of a Map...
Hey
I have been trying mock a OpenAPI version 3.0 and run into issues where the http://localhost:8080/_spec do not send path parameters with the request to the server.
It generates this url http://localhost/v1/screen/,
which should have been http://localhost/v1/screen/497f6eca-6276-1596-bfeb-53ceb43a6f54
. The OpenAPI definition works perfectly in https://editor.swagger.io/.
I can see that the swagger UI files in https://github.com/outofcoffee/imposter/tree/master/plugin/openapi/src/main/html have not be updated and the current release is v3.49.0 where the one in imposter is v3.24.3.
Would it be possible to update the swagger UI version to fix this issue
As imposter does not auto reload, (does it? ), it would be great to have a command like /system/status that reloads the config file. Could be : /system/reload
This way, mockup server should be usable by many people without going on a protected server to restart service to reload.
A smart groovy script could be a workaround... until the script is broken !
Thank you.
I try to reuse examples by placing them in components/examples ans referencing them with $ref but imposter does seams to not support it (example here: https://swagger.io/docs/specification/adding-examples/ 'Reusing Examples')
Do you think iy would be possible to integrate this feature?
Is it possible to implement example creation based on model definition in open api plugin (swagger ui)
Would want to implement something like that, because we need it, but dont want to give time into taht if this isnt possible
Hi,
is it possible to run sfdc with simple_salesforce as a client?
I run the mock:
docker run -ti -p 8080:8080
-p 443:443
-v $(pwd)/config:/opt/imposter/config
-v $(pwd)/keystore:/opt/imposter/keystore
outofcoffee/imposter-sfdc -c /opt/imposter/config
--tlsEnabled
--listenPort 443
--serverUrl http://localhost:443
--keystorePath /opt/imposter/keystore/ssl.jks
--keystorePassword password
Then I just use:
from simple_salesforce import Salesforce
sf = Salesforce(instance_url='https://127.0.0.1', session_id='')
sf.Contact.create({'LastName':'Smith','Email':'[email protected]'})
And get error:
requests.exceptions.SSLError: HTTPSConnectionPool(host='127.0.0.1', port=443): Max retries exceeded with url: /services/data/v38.0/sobjects/Contact/ (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])")))
If you know a way to make simple-salesforce work without ssl, it will also help me.
Thanks.
docker run -ti -p 8080:8080 \
-v $(pwd)/config:/opt/imposter/config \
outofcoffee/imposter-openapi \
--configDir /opt/imposter/config
16:21:21 DEBUG c.g.i.s.ImposterLauncher - No plugins specified - attempting to load defaults
16:21:21 DEBUG c.g.i.s.ImposterVerticle - Initialising mock server
16:21:21 INFO c.g.i.Imposter - Starting mock engine
16:21:21 DEBUG c.g.i.Imposter - Loading configuration file: /opt/imposter/config/openapi2-config.json
16:21:21 INFO c.g.i.Imposter - Loaded 1 plugin configuration files from: [/opt/imposter/config]
16:21:21 DEBUG c.g.i.Imposter - Registered plugin com.gatehill.imposter.plugin.detector.PluginDetectorImpl
16:21:21 DEBUG c.g.i.Imposter - 1 plugins provided by com.gatehill.imposter.plugin.detector.PluginDetectorImpl
16:21:21 DEBUG c.g.i.Imposter - Registered plugin com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl
16:21:21 INFO c.g.i.Imposter - Loaded 2 plugins
16:21:22 DEBUG c.g.i.p.o.u.OpenApiVersionUtil - Using version: V2 parser for: /opt/imposter/config/kfp_api_single_file.swagger.json
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: GET -> /apis/v1beta1/runs
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: POST -> /apis/v1beta1/runs
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: DELETE -> /apis/v1beta1/runs/:id
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: POST -> /apis/v1beta1/runs/:id:archive
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: POST -> /apis/v1beta1/runs/:id:unarchive
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: GET -> /apis/v1beta1/runs/{run_id}
16:21:22 DEBUG c.g.i.p.o.OpenApiPluginImpl - Adding mock endpoint: GET -> /apis/v1beta1/runs/{run_id}/nodes/{node_id}/artifacts/{artifact_name}:read
java.util.regex.PatternSyntaxException: Illegal repetition near index 18
/apis/v1beta1/runs/{run_id}/nodes/{node_id}/artifacts/{artifact_name}(?<p0>[^/]+)
^
at java.util.regex.Pattern.error(Pattern.java:1957)
at java.util.regex.Pattern.closure(Pattern.java:3159)
at java.util.regex.Pattern.sequence(Pattern.java:2136)
at java.util.regex.Pattern.expr(Pattern.java:1998)
at java.util.regex.Pattern.compile(Pattern.java:1698)
at java.util.regex.Pattern.<init>(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at io.vertx.ext.web.impl.RouteImpl.createPatternRegex(RouteImpl.java:397)
at io.vertx.ext.web.impl.RouteImpl.setPath(RouteImpl.java:353)
at io.vertx.ext.web.impl.RouteImpl.<init>(RouteImpl.java:68)
at io.vertx.ext.web.impl.RouterImpl.route(RouterImpl.java:89)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$handlePathOperations$4(OpenApiPluginImpl.java:134)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.handlePathOperations(OpenApiPluginImpl.java:128)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$null$0(OpenApiPluginImpl.java:104)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$configureRoutes$1(OpenApiPluginImpl.java:103)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.configureRoutes(OpenApiPluginImpl.java:98)
at com.gatehill.imposter.server.ImposterVerticle.lambda$configureRoutes$4(ImposterVerticle.java:86)
at java.util.HashMap$Values.forEach(HashMap.java:981)
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080)
at com.gatehill.imposter.server.ImposterVerticle.configureRoutes(ImposterVerticle.java:86)
at com.gatehill.imposter.server.ImposterVerticle.lambda$start$0(ImposterVerticle.java:50)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:271)
at io.vertx.core.impl.TaskQueue.lambda$new$0(TaskQueue.java:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
16:21:22 ERROR i.v.c.i.l.c.VertxIsolatedDeployer - Failed in deploying verticle
java.util.regex.PatternSyntaxException: Illegal repetition near index 18
/apis/v1beta1/runs/{run_id}/nodes/{node_id}/artifacts/{artifact_name}(?<p0>[^/]+)
^
at java.util.regex.Pattern.error(Pattern.java:1957) ~[?:1.8.0_212]
at java.util.regex.Pattern.closure(Pattern.java:3159) ~[?:1.8.0_212]
at java.util.regex.Pattern.sequence(Pattern.java:2136) ~[?:1.8.0_212]
at java.util.regex.Pattern.expr(Pattern.java:1998) ~[?:1.8.0_212]
at java.util.regex.Pattern.compile(Pattern.java:1698) ~[?:1.8.0_212]
at java.util.regex.Pattern.<init>(Pattern.java:1351) ~[?:1.8.0_212]
at java.util.regex.Pattern.compile(Pattern.java:1028) ~[?:1.8.0_212]
at io.vertx.ext.web.impl.RouteImpl.createPatternRegex(RouteImpl.java:397) ~[imposter-openapi.jar:?]
at io.vertx.ext.web.impl.RouteImpl.setPath(RouteImpl.java:353) ~[imposter-openapi.jar:?]
at io.vertx.ext.web.impl.RouteImpl.<init>(RouteImpl.java:68) ~[imposter-openapi.jar:?]
at io.vertx.ext.web.impl.RouterImpl.route(RouterImpl.java:89) ~[imposter-openapi.jar:?]
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$handlePathOperations$4(OpenApiPluginImpl.java:134) ~[imposter-openapi.jar:?]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[?:1.8.0_212]
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.handlePathOperations(OpenApiPluginImpl.java:128) ~[imposter-openapi.jar:?]
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$null$0(OpenApiPluginImpl.java:104) ~[imposter-openapi.jar:?]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[?:1.8.0_212]
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$configureRoutes$1(OpenApiPluginImpl.java:103) ~[imposter-openapi.jar:?]
at java.util.ArrayList.forEach(ArrayList.java:1257) ~[?:1.8.0_212]
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.configureRoutes(OpenApiPluginImpl.java:98) ~[imposter-openapi.jar:?]
at com.gatehill.imposter.server.ImposterVerticle.lambda$configureRoutes$4(ImposterVerticle.java:86) ~[imposter-openapi.jar:?]
at java.util.HashMap$Values.forEach(HashMap.java:981) ~[?:1.8.0_212]
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080) ~[?:1.8.0_212]
at com.gatehill.imposter.server.ImposterVerticle.configureRoutes(ImposterVerticle.java:86) ~[imposter-openapi.jar:?]
at com.gatehill.imposter.server.ImposterVerticle.lambda$start$0(ImposterVerticle.java:50) ~[imposter-openapi.jar:?]
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:271) ~[imposter-openapi.jar:?]
at io.vertx.core.impl.TaskQueue.lambda$new$0(TaskQueue.java:60) ~[imposter-openapi.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_212]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
java.util.regex.PatternSyntaxException: Illegal repetition near index 18
/apis/v1beta1/runs/{run_id}/nodes/{node_id}/artifacts/{artifact_name}(?<p0>[^/]+)
^
at java.util.regex.Pattern.error(Pattern.java:1957)
at java.util.regex.Pattern.closure(Pattern.java:3159)
at java.util.regex.Pattern.sequence(Pattern.java:2136)
at java.util.regex.Pattern.expr(Pattern.java:1998)
at java.util.regex.Pattern.compile(Pattern.java:1698)
at java.util.regex.Pattern.<init>(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at io.vertx.ext.web.impl.RouteImpl.createPatternRegex(RouteImpl.java:397)
at io.vertx.ext.web.impl.RouteImpl.setPath(RouteImpl.java:353)
at io.vertx.ext.web.impl.RouteImpl.<init>(RouteImpl.java:68)
at io.vertx.ext.web.impl.RouterImpl.route(RouterImpl.java:89)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$handlePathOperations$4(OpenApiPluginImpl.java:134)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.handlePathOperations(OpenApiPluginImpl.java:128)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$null$0(OpenApiPluginImpl.java:104)
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.lambda$configureRoutes$1(OpenApiPluginImpl.java:103)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl.configureRoutes(OpenApiPluginImpl.java:98)
at com.gatehill.imposter.server.ImposterVerticle.lambda$configureRoutes$4(ImposterVerticle.java:86)
at java.util.HashMap$Values.forEach(HashMap.java:981)
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080)
at com.gatehill.imposter.server.ImposterVerticle.configureRoutes(ImposterVerticle.java:86)
at com.gatehill.imposter.server.ImposterVerticle.lambda$start$0(ImposterVerticle.java:50)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:271)
at io.vertx.core.impl.TaskQueue.lambda$new$0(TaskQueue.java:60)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Accidentally shut down,please look here
#15
Hi, is there a way to get a specific property of a JSON that is being sent in a request in a groovy script? context.request.body
returns a plain string and I'm unable to use groovy.json.JsonSlurper to parse as I'm getting unable to resolve class groovy.json.JsonSlurper
when I try to import it.
Paths in combined specification should be rewritten to respect any base path set in configuration.
I have a spec file in which the example is provided in the definition.
Just because there is no examples it doesn't send a response.
Here's an example:
---
swagger: "2.0"
info:
version: "1.0.0"
title: "Swagger Petstore"
consumes:
- "application/json"
produces:
- "application/json"
paths:
/pets:
get:
description: "Returns all pets from the system"
produces:
- "application/json"
responses:
"200":
description: "A list of pets."
schema:
items:
$ref: "#/definitions/Pet"
definitions:
Pet:
type: "object"
required:
- "id"
- "name"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
example:
"id": 101,
"name": "Cat"
Hi,
first I would like to say thanks for this awesome software. I've been using it for a few OAS projects now and it's really great and useful.
I've noticed a little problem a couple of times though. When using Swagger UI, some things do not work. I've done some research and the problem seems to be, that some property values are transformed to uppercase when imposter produces the combined.json.
For example, when securitySchemes are defined in the spec with type: http, in combined.json it reads type: HTTP. Swagger UI doesn't like this, apparently, and so the authentication popup is blank when it opens. From the OpenAPI documentation it looks like the value should be lowercase.
The same happens with the style property of operation parameters.
I'm building my own docker container based on outofcoffee/imposter-openapi.
Can you give me a hint on how to fix this?
Thanks!
Jan
Hi!
There is some way to connect a groovy script to an Oracle Database using ojdbc6.jar?
I've been trying to build muy own docker image from the openapi plugin image, and copy the .jar to some paths (lib), but always get a java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
Thanks for reading!
Awesome project!!
Hi,
do you intent to support openapi spec 3.* in the near future?
Today, Imposter uses examples specified in the responses
section of an API. In the OpenAPI specification it is also possible to have examples in the model definitions.
Collect examples from model definitions, and use them if a response example does not exist.
As per #5
I'm running mutiple Imposter instances (openAPI) as docker containers which once a while are crashing with exit code 137 because they are allocating too much memory.
I was wondering if we could mock multiple services inside a single JVM. Is there any way to pass multiple configurations (one for each mock service) to Imposter? I guess this way the total amount of memory would be reduced.
I've also noticed Imposter uses an OpenJDK 8 Docker Image and according to its documentation:
Inside Linux containers, OpenJDK versions 8 and later can correctly detect container-limited number of CPU cores and available RAM.
In OpenJDK 11 this is turned on by default. In versions 8, 9, and 10 you have to enable the detection of container-limited amount of RAM using the following options:
$ java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap...
I'm not sure, but maybe those flags could help to keep memory consumption under control.
hi can i assign other port like this e.g: 8084. when i docker run command the port is ignored.
docker run --rm -ti --network host -p 8084:8080 \
-v $(pwd):/opt/imposter/config \
outofcoffee/imposter-openapi
In various tutorials/documentation we use Swagger/OAS 2.x format specifications.
We should update these with their OAS 3.x equivalents.
When an unknown ID is used imposter says it can't find it
14:59:28 ERROR i.g.i.p.s.SfdcPluginImpl - Account SObject with ID: 0015000000VALDtBBB not found
but it doesn't send a correct response to ForceApi and I get
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
at Main_Scriptlet_fc96736f82df81e8$Companion.main(Main_Scriptlet_fc96736f82df81e8.kt:6)
at Main_Scriptlet_fc96736f82df81e8.main(Main_Scriptlet_fc96736f82df81e8.kt)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:64)
at org.jetbrains.kotlin.runner.Main.run(Main.kt:176)
at org.jetbrains.kotlin.runner.Main.main(Main.kt:186)
Caused by: java.lang.RuntimeException: java.io.IOException: Stream closed
at com.force.api.http.Http.send(Http.java:118)
at com.force.api.ForceApi.apiRequest(ForceApi.java:499)
at com.force.api.ForceApi.getSObject(ForceApi.java:206)
at Scriptlet_fc96736f82df81e8.<init>(scriptlet.fc96736f82df81e8.kts:25)
... 13 more
Caused by: java.io.IOException: Stream closed
at java.base/java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:165)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:290)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)
at com.force.api.http.Http.readResponse(Http.java:57)
at com.force.api.http.Http.send(Http.java:113)
... 16 more
Hi!
I have a swagger.json file that responds with the same response:
The response for this get:
"/comments": {
"get": {
"summary": "Get Comments",
"description": "Get the comments based on data",
"operationId": "getComments",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Successful operation",
"headers": {},
"schema": {
"$ref": "#/definitions/CommentResponse"
},
"examples": {
"application/json" : "{\n"results" : 1, \n"items" : [\n\t{\n\t"id" : 1,\n\t"user" : "user",\n\t"creationTimestamp" : "2019-09-13T14:32:35.203Z",\n\t"content" : "This is a comment"]}"
}
},
Is exactly as the one for the following:
"/comments/users": {
"get": {
"summary": "Get all users",
"operationId": "getUsers",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Successful operation",
"schema": {
"$ref": "#/definitions/UsersResponse"
},
"examples": {
"application/json" : "{\n"results" : 4, \n"items" : [\n\t{\n\t\t "name" : "user1" \n\t},\n\t{ \n\t\t "name" : "user2" \n\t}, \n\t{ \n\t\t "name" : "user3" \n\t}, \n\t{ \n\t\t"name" : "user4" \n\t}"
}
},
I didn't used any groovy scripts or something else. Only one -config file to get the swagger.json file and one docker-compose to run the docker image.
Any ideas why this is happenning?
This:
11:56:26.779 [vert.x-eventloop-thread-0] INFO com.gatehill.imposter.server.ImposterVerticle - Starting mock server on 0.0.0.0:8443
...is too long. Should be:
11:56:26 INFO c.g.i.s.ImposterVerticle - Starting mock server on 0.0.0.0:8443
From https://github.com/outofcoffee/imposter/blob/master/docs/rest_plugin.md#multiple-paths I understand that I can access element from an array like the examples of cats and dogs. however what if the array element also contains an array
Imagine I want to mock a call like cats/:id/owners
and cats/:id/owners/:ownerid
. where the first one would return the full array and the second only a specific owner using its id.
How can I mock a rest api like this one ?
Hi,
I have a question about https://github.com/outofcoffee/imposter
I dockerize this mock server for development purpose but from my web application in Angular (that call the rest services mocked) I have the cors policy issue.
How can I do? I need a gateway between webapp and our mocks on server-side?
Thanks in advance.
When a path in the swagger specifies a specific set of response codes, a 200 response is always returned. Assume the following swagger fragment:
paths:
'/Order/{orderId}':
put:
consumes:
- application/json
produces: []
parameters:
- name: order
in: body
required: false
schema:
$ref: '#/definitions/Order'
responses:
'202':
description: Request to put the order has been accepted.
'400':
description: Bad Request
Imposter seems to always respond with a 200 response and not a 202.
Firstly thankyou for this tool. I didn't think it would be so hard to find a tool that would mock/stub the spec and return example responses.
However the ExampleService
assumes that the response is inlined ie:
{
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
...
},
"examples": {
"application/json": {
"value": {
...
}
}
}
}
}
}
}
}
If however, I use a Reference Object the example is not found ie:
{
"responses": {
"200": {
"$ref": "#/components/responses/myResponse"
}
}
}
Unfortunately my entire spec uses response references, so for me to use this tool I need the reference to be followed.
It seems impossible to load a script using withFile(filename).template()
. In order to have different scripts doing different actions but share common code (like decoding parameters, storing in stores etc..) a function withScript(String) would be useful. Of course the request store should be available through all those scripts for the whole life cycle of the current HTTP request like it is today even if multiple scripts are called.
For instance I'd like to do something like
# mock-config.yaml
plugin: rest
resources:
- path: /my/path
method: POST
response:
scriptFile: dispatcher.groovy
// dispatcher.groovy
def requestStore = stores.open('request')
def queryParams = context.request.body.split('&').collectEntries {
param -> param.split('=').collect { URLDecoder.decode(it) }
}
// store all important params in request store
...
// do some other stuff like storing calculating values in request store
...
// check if queryParams.wsfunction is known and call the corresponding script
if (....){
respond()
.withScript("${queryParams.wsfunction}.groovy")
else{
respond()
.withStatusCode(400)
.skipDefaultBehaviour()
}
This is more a question. Can I generate a state on groovy, and retrieve that state later on a GET ? For example POST to /users and then GET /users/{created_user}. does the groovy script support some kind of shared state ?
SFDC plugin
Test Step - Send a HTTP POST request to sfdc auth endpoint.
Expected Outcome - Response should contain a Content-Type header
Observe Outcome - The http response from the auth endpoint has no content type header.
I think it should have Content-Type: application/json
Will put in a PR
Example response from imposter service sfdc plugin is:
HTTP/1.1 200 OK
Content-Length: 74
{"access_token":"dummyAccessToken","instance_url":"http://localhost:8443"}
Hi, Can you guide me on how to include CORS headers in API responses? Thank you.
I'm trying to use this feature that was introduced in 2.9.0, however it doesn't work. Here is the configuration I use
plugin: rest
resources:
- method: GET
path: /example
requestBody:
jsonPath: $.foo
value: bar
response:
statusCode: 500
- method: GET
path: /example
requestBody:
jsonPath: $.baz
value: 99
response:
statusCode: 302
But when trying to query the same path with a different body I would expect the 1st rule, the 2nd rule, or none of them to match. However I see 3 issues:
Here are my different tests
Query with baz having value "99" (string) which should not match any rule
/ # curl -v -d '{"baz": "99"}' -X GET http://localhost:8888/example
* Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET /example HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 13
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< X-Imposter-Request: 2b60c533-ac0e-4e7d-9693-522fe17ff8c7
< Server: imposter
< content-length: 0
<
* Connection #0 to host localhost left intact
imposter side
22:04:30 DEBUG i.g.i.s.ResourceServiceImpl - Matched response config for GET /example
22:04:30 DEBUG i.g.i.s.ResponseServiceImpl - Using default HTTP 500 response behaviour for request: GET http://localhost:8888/example
22:04:30 INFO i.g.i.p.r.RestPluginImpl - Handling GET object request for: http://localhost:8888/example
22:04:30 INFO i.g.i.s.ResponseServiceImpl - Response file and data are blank - returning empty response for [a36b0a8e-9d3c-42ed-baf8-d56baae04381] GET http://localhost:8888/example
Query with baz having value 99 (integer) which should match 2nd rule
/ # curl -v -d '{"baz": 99}' -X GET http://localhost:8888/example
* Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET /example HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 11
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< X-Imposter-Request: 922038ea-773c-40f7-a1f9-fcf63647a90d
< Server: imposter
< content-length: 0
<
* Connection #0 to host localhost left intact
imposter side (See that it doesn't match response config)
22:04:49 DEBUG i.g.i.s.ResponseServiceImpl - Using default HTTP 500 response behaviour for request: GET http://localhost:8888/example
22:04:49 INFO i.g.i.p.r.RestPluginImpl - Handling GET object request for: http://localhost:8888/example
22:04:49 INFO i.g.i.s.ResponseServiceImpl - Response file and data are blank - returning empty response for [4514ace6-ddd0-4e11-b867-0a38e756fec5] GET http://localhost:8888/example
Query with neither foo nor baz having expected values which should not match any rule but still returns default response from 1st rule. Why is it the default ? It shouldn't match at all
/ # curl -v -d '{"no-known-key": "a-value"}' -X GET http://localhost:8888/example
* Trying 127.0.0.1:8888...
* Connected to localhost (127.0.0.1) port 8888 (#0)
> GET /example HTTP/1.1
> Host: localhost:8888
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 27
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 500 Internal Server Error
< X-Imposter-Request: 6238b636-b576-4900-9f5b-6c2a63c0b67d
< Server: imposter
< content-length: 0
<
* Connection #0 to host localhost left intact
imposter side
22:06:25 DEBUG i.g.i.s.ResponseServiceImpl - Using default HTTP 500 response behaviour for request: GET http://localhost:8888/example
22:06:25 INFO i.g.i.p.r.RestPluginImpl - Handling GET object request for: http://localhost:8888/example
22:06:25 INFO i.g.i.s.ResponseServiceImpl - Response file and data are blank - returning empty response for [6238b636-b576-4900-9f5b-6c2a63c0b67d] GET http://localhost:8888/example
Nashorn, the provider of JavaScript scripting support is deprecated as of Java 11.
The GraalVM implementation is intended to eventually replace the Nashorn implementation.
How to enable https with a Key & Cert instead of jks
Hello! Thank you for this project!
Any plans to publish a docker image with arm64 support? This would be very helpful for those running the project on arm based machines like the M1 mac chips. Thanks again!
I believe I am passing a valid request for the specification
swagger: "2.0"
info:
version: "2021-11-03T14:58:25Z"
title: "charges-dev"
host: "localhost:8080"
basePath: "/charges"
schemes:
- "https"
- "http"
paths:
/myendoint:
post:
tags:
- "tags"
summary: "Post endpoint"
description: "takes a payload
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "PostBody"
description: "Post Body"
required: true
schema:
$ref: "#/definitions/PostBodyDef
curl --location --request POST 'localhost:8080/charges/myendpoint/' \ --header 'Content-Type: application/json' \ --data-raw ' [ { ....
Paths match
Verbs match
Payload matches
Config
plugin: openapi specFile: output.yml validation: request: true levels: validation.request.body.missing: WARN validation.request.body.unexpected: WARN validation.request.path.missing: ERROR
What else do I need to match?
io.vertx.core.http.HttpServer#listen(int, java.lang.String, io.vertx.core.Handler<io.vertx.core.AsyncResult<io.vertx.core.http.HttpServer>>)
should not be called from the main thread
Currently, from the open api spec, when I start imposter , I'm able to start server and access my endpoint via API. When I invoke API, I'm able to get the response which I have configured as example in open api spec. If I configure, multiple examples, it's always returning the last example mentioned in openapi spec. Is there an option that we can configure to pick the reponse like a round robin behavior on the examples available rather than picking the last example all the time
It would be nice for testing if importer would be available in Maven central and it could be handled same way as other (test) dependencies.
How do we run the Docker command to start the Mock Server in the NPM script.
http://localhost:8443/_spec will show blank page, can't show swagger ui page ,what's the matter,
i run java -jar distro/build/libs/imposter.jar --plugin com.gatehill.imposter.plugin.openapi.OpenApiPluginImpl --configDir d:/config
Hi,
I am facing an issue where I am receiving same responses if the request paths overlap like if request 1 path is /tests
and request 2 path is /tests/results and I am receiving the response of /tests even if I am trying out the second request /tests/results, this is happening in case of both the _spec url with swaggerUI and while requesting via postman as well, is there a configuration that I am missing?
This same issue was describe in the following link
#34 (comment)
but it was closed without any resolution.
For your repository to truly be open source, you'll need to license it so that others are free to use, change, and distribute the software.
https://help.github.com/articles/licensing-a-repository/
I use OpenAPI. I have multiple responses for each path, including error responses like 404
, 409
etc.
Is there a way to trigger an API call to to test error codes?
Example:
/rest/api/2/project/{projectIdOrKey}:
get:
tags:
- jira
summary: get project
operationId: getProject
description: Gets information about a project
parameters:
- in: path
name: projectIdOrKey
schema:
type: string
required: true
example: TEST
description: Numeric ID or key of the project
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Project'
'404':
description: The project is not found, or the calling user does not have permission to view it.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
First of all: this project is awesome and it saves us a lot of time. I really appreciate your work ๐
We have a config for POST /
request, it emulates Amazon STS Assume Role endpoint, so it looks like this:
---
plugin: rest
resources:
- path: "/"
method: POST
response:
staticData: |
<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
...
Locally we don't have any problem but when we try it in the Kubernetes cluster we started to see 500 Internal Errors with the exception of about access denied, vertx, and /file-uploads
. I think it is because in our Pod we usually have a read-only filesystem, but Imposter tries to write something into it.
It is reproduced only with application/x-www-form-urlencoded
in Content-Type and on a read-only filesystem, so it is my example of a request:
In [23]: httpx.post('http://imposter').content
Out[23]: b'<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">\n...\n'
In [24]: httpx.post('http://imposter',headers={'Content-Type': b'application/x-www-form-urlencoded; charset=utf-8'}).content
Out[24]: b'Internal Server Error'
Hello,
Great tool. I absolutely think this is so cool. One issue I did run into tho is that when I try to use the swagger api specification UI and need to enter a value for a path parameter, the curl statement shows as if i did not enter the param value and instead it places a comma in where the path parameter value should be and then results in a response of
I am using the latest docker image and tried both imposter-openapi and imposter and same issue.
I am running on mac Big Sur 11.6 and google chrome Version 95.0.4638.69 (Official Build) (x86_64)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.