Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mocking plugin #5940

Merged
merged 63 commits into from Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
befb95c
feat: mocking plugin
Dec 27, 2021
ff1b662
fix: fix code lint
Dec 28, 2021
1c38b88
feat: support delay,status,content-type and response_example
Jan 6, 2022
2f09041
fix: random gen boolean
Jan 6, 2022
c5c7449
Update docs/zh/latest/plugins/mocking.md
Drery Jan 10, 2022
ab7dd01
Update docs/zh/latest/plugins/mocking.md
Drery Jan 10, 2022
8b15af7
fix: coding lint
Jan 10, 2022
4a27281
feat: with mock header
Jan 10, 2022
cefcaf2
feat: with mock header
Jan 10, 2022
41df69a
fix: update md
Jan 10, 2022
f807386
fix: update md
Jan 10, 2022
f86fd49
feat: add xml2lua rock spec
Jan 14, 2022
0a02f27
fix: update md
Jan 14, 2022
a351ded
Update apisix/plugins/mocking.lua
Drery Jan 18, 2022
9848555
Update docs/zh/latest/plugins/mocking.md
Drery Jan 18, 2022
9190d27
Update docs/zh/latest/plugins/mocking.md
Drery Jan 18, 2022
27d6d1b
Update apisix/plugins/mocking.lua
Drery Jan 18, 2022
439cf14
Update apisix/plugins/mocking.lua
Drery Jan 18, 2022
0c296b5
feat: local function
Jan 19, 2022
0d92b43
Merge branch 'master' of github.com:Drery/apisix
Jan 19, 2022
5fb3647
fix: fix code lint
Jan 20, 2022
a62f7a8
feat: add en md
Jan 21, 2022
e66a680
fix: fix conflicts
Jan 21, 2022
db37e2d
feat: add plugin in config-default.yaml
Jan 21, 2022
71e9af1
fix: add mocking plugin in plugin.t
Jan 23, 2022
a42a7fe
feat: add mocking test
Jan 23, 2022
67e5496
feat: update mocking test
Jan 23, 2022
ebfe46f
feat: update mocking
Jan 24, 2022
b894f95
feat: remove chomp
Jan 24, 2022
1454033
Update apisix/plugins/mocking.lua
Drery Jan 25, 2022
6ff7f11
Update apisix/plugins/mocking.lua
Drery Jan 25, 2022
ce39d6c
Update apisix/plugins/mocking.lua
Drery Jan 25, 2022
7f900bb
Update apisix/plugins/mocking.lua
Drery Jan 25, 2022
08a0c55
feat: fix some issue
Jan 25, 2022
6fb6b0c
feat: merge update
Jan 25, 2022
8f374f3
Update apisix/plugins/mocking.lua
Drery Jan 26, 2022
514f0af
feat: fix lint
Jan 26, 2022
bebc44a
Merge branch 'master' of github.com:Drery/apisix
Jan 26, 2022
6fd29c6
feat: merge upstram master
Jan 26, 2022
e525a84
fix test case
Jan 27, 2022
ed9ae66
Merge remote-tracking branch 'upstream/master'
Jan 27, 2022
10fdc1d
remove array test
Jan 27, 2022
d693611
Merge remote-tracking branch 'upstream/master'
Jan 30, 2022
968fdb2
feat: merge upstream
Jan 30, 2022
43ac0de
Merge remote-tracking branch 'upstream/master'
Feb 8, 2022
5a54066
fix: batch-requests plugin
Feb 8, 2022
288f7e0
fix: change tapisix to apisix in md file
Feb 9, 2022
49fdd59
gen by property
Feb 14, 2022
7da4aa6
remove batch-requests in plugin.t
Feb 14, 2022
2f2cffc
Merge remote-tracking branch 'upstream/master'
Feb 14, 2022
f5d9529
fix: add response in mocking.t
Feb 15, 2022
9d511c6
Update docs/en/latest/plugins/mocking.md
Drery Feb 15, 2022
f87bf28
fix: format code and doc
Feb 16, 2022
65447a2
Merge branch 'master' of github.com:Drery/apisix
Feb 16, 2022
95c7678
fix: format code and doc
Feb 16, 2022
e88b7d5
feat: update plugin priority
Feb 16, 2022
6f7a256
feat: sort
Feb 16, 2022
396d2a9
feat: update priority
Feb 16, 2022
9e0b57b
Update docs/en/latest/plugins/mocking.md
Drery Feb 16, 2022
e7cfd2f
Update docs/en/latest/plugins/mocking.md
Drery Feb 16, 2022
45047e5
feat: fix conflict
Feb 18, 2022
502a69b
Merge branch 'master' of github.com:Drery/apisix
Feb 18, 2022
b1b789c
Update conf/config-default.yaml
spacewander Feb 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
160 changes: 160 additions & 0 deletions apisix/plugins/mocking.lua
@@ -0,0 +1,160 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local core = require("apisix.core")
local ngx = ngx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's sort the statements to make the require in a group.

local plugin_name = "mocking"
Drery marked this conversation as resolved.
Show resolved Hide resolved

local schema = {
type = "object",
properties = {
response_schema = { type = "object" }
},
required = { "response_schema" }
}

local _M = {
version = 0.1,
priority = 9900,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to update the priority in the code

name = plugin_name,
schema = schema,
}

function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
Drery marked this conversation as resolved.
Show resolved Hide resolved
if not ok then
return false, err
end

if conf.response_schema then
Drery marked this conversation as resolved.
Show resolved Hide resolved
ok, err = core.schema.valid(conf.response_schema)
if not ok then
return false, err
end
end

return true, nil
end

Drery marked this conversation as resolved.
Show resolved Hide resolved
function _M.rewrite(conf)
Drery marked this conversation as resolved.
Show resolved Hide resolved
if conf.response_schema then
Drery marked this conversation as resolved.
Show resolved Hide resolved
local output = genObject(conf.response_schema)
ngx.header["Content-Type"] = "application/json"
return 200, core.utils.resolve_var(core.json.encode(output))
end
end

function genObject(property)
Drery marked this conversation as resolved.
Show resolved Hide resolved
local output = {}
if property.properties == nil then
return output
end
for k, v in pairs(property.properties) do
if v.type == "array" then
output[k] = genArray(v)
elseif v.type == "object" then
output[k] = genObject(v)
else
output[k] = genBase(v)
end
end
return output
end

function genArray(property)
local output = {}
if property.items == nil then
return nil
end
local v = property.items
local n = math.random(1, 3)
for i = 1, n do
if type == "array" then
table.insert(output, genArray(v))
elseif type == "object" then
table.insert(output, genObject(v))
else
table.insert(output, genBase(v))
end
end
return output
end

function genBase(property)
local type = property.type
local example = property.example
if type == "string" then
return genString(example)
elseif type == "number" then
return genNumber(example)
elseif type == "integer" then
return genInteger(example)
elseif type == "boolean" then
return genBoolean(example)
end
return nil
end

function genString(example)
if example ~= nil and type(example) == "string" then
Drery marked this conversation as resolved.
Show resolved Hide resolved
Drery marked this conversation as resolved.
Show resolved Hide resolved
return example
end
local t = {
Drery marked this conversation as resolved.
Show resolved Hide resolved
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
}
local n = math.random(1, 10)
local s = ""
for i = 1, n do
s = s .. t[math.random(#t)]
Drery marked this conversation as resolved.
Show resolved Hide resolved
end ;
Drery marked this conversation as resolved.
Show resolved Hide resolved
return s
end

function genNumber(example)
if example ~= nil and type(example) == "number" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same and take care of similar rest of them

return example
end
return math.random() * 10000
end

function genInteger(example)
if example ~= nil and type(example) == "number" then
return math.floor(example)
end
return math.random(1, 10000)
end

function genBoolean(example)
if example ~= nil and type(example) == "boolean" then
return example
end
local r = math.random(0, 2)
Drery marked this conversation as resolved.
Show resolved Hide resolved
if r == 0 then
return false
end
return true
end

return _M







196 changes: 196 additions & 0 deletions docs/zh/latest/plugins/mocking.md
@@ -0,0 +1,196 @@
---
title: limit-req
Drery marked this conversation as resolved.
Show resolved Hide resolved
---

<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->

## 目录

- [简介](#简介)
- [属性](#属性)
- [示例](#示例)
Drery marked this conversation as resolved.
Show resolved Hide resolved
- [如何在 `route` 或 `service` 上使用](#如何在`route`或`service`上使用)
- [如何在 `consumer` 上使用](#如何在`consumer`上使用)
- [移除插件](#移除插件)

## 简介

Mock API插件,绑定该插件后将随机返回指定格式的mock数据,不再转发到后端。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add space around English word


## 属性

| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
| ------------- | ------- | ------ | ------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| response_schema | object | 必须 | | | 响应的json schema对象。具体结构看后文说明。 |
支持的字段类型:string,number,integer,boolean,object,array。
Drery marked this conversation as resolved.
Show resolved Hide resolved
基础数据类型(string,number,integer,boolean)可通过配置example属性指定生成的响应值,未配置时随机返回。
Drery marked this conversation as resolved.
Show resolved Hide resolved
以下是一个json schema实例:
```json
{
"properties":{
"field0":{
"example":"abcd",
"type":"string"
},
"field1":{
"example":123.12,
"type":"number"
},
"field3":{
"properties":{
"field3_1":{
"type":"string"
},
"field3_2":{
"properties":{
"field3_2_1":{
"example":true,
"type":"boolean"
},
"field3_2_2":{
"items":{
"example":155.55,
"type":"integer"
},
"type":"array"
}
},
"type":"object"
}
},
"type":"object"
},
"field2":{
"items":{
"type":"string"
},
"type":"array"
}
},
"type":"object"
}
```
以下为该json schema可能生成的返回对象:
```json
{
"field1": 123.12,
"field3": {
"field3_1": "LCFE0",
"field3_2": {
"field3_2_1": true,
"field3_2_2": [
155,
155
]
}
},
"field0": "abcd",
"field2": [
"sC"
]
}
```

## 示例

### 如何在`route`或`service`上使用

这里以`route`为例(`service`的使用是同样的方法),在指定的 `route` 上启用 `mocking` 插件。

```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"plugins": {
"mocking": {
"response_schema": {
"properties":{
"field0":{
"example":"abcd",
"type":"string"
},
"field1":{
"example":123.12,
"type":"number"
},
"field3":{
"properties":{
"field3_1":{
"type":"string"
},
"field3_2":{
"properties":{
"field3_2_1":{
"example":true,
"type":"boolean"
},
"field3_2_2":{
"items":{
"example":155.55,
"type":"integer"
},
"type":"array"
}
},
"type":"object"
}
},
"type":"object"
},
"field2":{
"items":{
"type":"string"
},
"type":"array"
}
},
"type":"object"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```

## 移除插件

当你想去掉 mocking 插件的时候,很简单,在插件的配置中把对应的 json 配置删除即可,无须重启服务,即刻生效:

```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```

现在就已经移除了 mocking 插件了。其他插件的开启和移除也是同样的方法。