This is an automated email from the ASF dual-hosted git repository.
hefengen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 7178b824e [ISSUE #4891] <Add a locking mechanism to solve the problem
of repeatedly inserting swagger apidoc&modify the swagger example.> (#4892)
7178b824e is described below
commit 7178b824e9f6554ae27eb8bfea70f3b27a200fa9
Author: lianjunwei <[email protected]>
AuthorDate: Mon Jul 24 20:07:31 2023 +0800
[ISSUE #4891] <Add a locking mechanism to solve the problem of repeatedly
inserting swagger apidoc&modify the swagger example.> (#4892)
* apidoc sql
* refact
* commit
* [Task] Shenyu-admin: Fix API document failed to build because of NPE.
* [Task] Shenyu-admin: Fix API document failed to build because of NPE.
* solve conficts,modify LICENSE.
* delete useless code.
* delete useless code.
* commit
* [ISSUE #3843]admin apidoc fix: the required attribute prompt is incorrect
when micro service parameter uses "@ApiModelProperty".
* commit
* [shenyu-examples]add swagger to the example project to test the apidoc
function of the gateway management system.
* commit
* commit
* commit
* [ISSUE #4690]Supports gzip compression in response to HTTP requests.
* [examples]Add Swagger sample project to demonstrate automatic pull
interface documentation.
* delete exapmple
* delete useless code.
* delete useless code.
* add doc lock, and modify swagger example.
* fix NPE.
---------
Co-authored-by: lianjunwei <[email protected]>
Co-authored-by: dragon-zhang <[email protected]>
Co-authored-by: xiaoyu <[email protected]>
---
.../apache/shenyu/admin/model/entity/TagDO.java | 18 +++++
.../org/apache/shenyu/admin/model/vo/TagVO.java | 18 +++++
.../apache/shenyu/admin/service/TagService.java | 11 ++-
.../shenyu/admin/service/impl/TagServiceImpl.java | 20 +++++-
.../manager/impl/LoadServiceDocEntryImpl.java | 11 ++-
.../manager/impl/PullSwaggerDocServiceImpl.java | 78 +++++++++++++++++-----
.../manager/impl/RegisterApiDocServiceImpl.java | 4 +-
.../http/ShenyuTestSwaggerApplication.java | 2 +-
.../http/controller/HttpTestController.java | 36 +++++++++-
.../examples/http/controller/OauthController.java | 4 --
.../examples/http/controller/OrderController.java | 2 +-
.../http/controller/RequestController.java | 7 +-
.../controller/SpringMvcMappingPathController.java | 12 ++--
.../examples/http/controller/UploadController.java | 10 +--
.../apache/shenyu/examples/http/dto/OrderDTO.java | 21 ++++++
.../shenyu/examples/http/dto/RequestDTO.java | 4 +-
.../{dto/OrderDTO.java => result/TreeResult.java} | 76 ++++++++++++++-------
17 files changed, 260 insertions(+), 74 deletions(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/TagDO.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/TagDO.java
index 22b85a421..314783652 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/TagDO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/TagDO.java
@@ -324,6 +324,8 @@ public final class TagDO extends BaseDO {
*/
private String apiDocMd5;
+ private String docLock;
+
/**
* get id.
* @return id
@@ -422,6 +424,22 @@ public final class TagDO extends BaseDO {
public void setApiDocMd5(final String apiDocMd5) {
this.apiDocMd5 = apiDocMd5;
}
+
+ /**
+ * get docLock.
+ * @return docLock
+ */
+ public String getDocLock() {
+ return docLock;
+ }
+
+ /**
+ * set docLock.
+ * @param docLock docLock
+ */
+ public void setDocLock(final String docLock) {
+ this.docLock = docLock;
+ }
}
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/TagVO.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/TagVO.java
index 52c4a368e..2e26c2dc3 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/TagVO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/TagVO.java
@@ -53,6 +53,8 @@ public class TagVO implements Serializable {
*/
private String ext;
+ private TagDO.TagExt tagExt;
+
/**
* created time.
*/
@@ -165,6 +167,22 @@ public class TagVO implements Serializable {
this.ext = ext;
}
+ /**
+ * get tagExt.
+ * @return tagExt
+ */
+ public TagDO.TagExt getTagExt() {
+ return tagExt;
+ }
+
+ /**
+ * set tagExt.
+ * @param tagExt tagExt
+ */
+ public void setTagExt(final TagDO.TagExt tagExt) {
+ this.tagExt = tagExt;
+ }
+
/**
* get create time.
* @return createtime
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/TagService.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/TagService.java
index cec65ffdb..fcce6e5cc 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/TagService.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/TagService.java
@@ -29,13 +29,22 @@ import org.apache.shenyu.admin.model.vo.TagVO;
public interface TagService {
/**
- * create or update tag.
+ * create tag.
*
* @param tagDTO {@linkplain TagDTO}
* @return rows int
*/
int create(TagDTO tagDTO);
+ /**
+ * create root tag.
+ *
+ * @param tagDTO tagDTO {@linkplain TagDTO}
+ * @param tagExt tagDTO {@linkplain TagDO.TagExt}
+ * @return rows int
+ */
+ int createRootTag(TagDTO tagDTO, TagDO.TagExt tagExt);
+
/**
* create or update tag.
*
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/TagServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/TagServiceImpl.java
index d453f5a7f..4210e6367 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/TagServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/TagServiceImpl.java
@@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.admin.mapper.TagMapper;
import org.apache.shenyu.admin.model.dto.TagDTO;
import org.apache.shenyu.admin.model.entity.BaseDO;
@@ -52,15 +53,30 @@ public class TagServiceImpl implements TagService {
@Override
public int create(final TagDTO tagDTO) {
+ tagDTO.setParentTagId(StringUtils.isNotEmpty(tagDTO.getParentTagId())
? tagDTO.getParentTagId() : AdminConstants.TAG_ROOT_PARENT_ID);
+ return createInner(tagDTO, null);
+ }
+
+ @Override
+ public int createRootTag(final TagDTO tagDTO, final TagDO.TagExt tagExt) {
+ Assert.notNull(tagDTO, "tagDTO is not allowed null");
+ tagDTO.setParentTagId(StringUtils.isNotEmpty(tagDTO.getParentTagId())
? tagDTO.getParentTagId() : AdminConstants.TAG_ROOT_PARENT_ID);
+ return createInner(tagDTO, tagExt);
+ }
+
+ private int createInner(final TagDTO tagDTO, final TagDO.TagExt tagExt) {
Assert.notNull(tagDTO, "tagDTO is not allowed null");
Assert.notNull(tagDTO.getParentTagId(), "parent tag id is not allowed
null");
String ext = "";
if
(!tagDTO.getParentTagId().equals(AdminConstants.TAG_ROOT_PARENT_ID)) {
TagDO tagDO =
tagMapper.selectByPrimaryKey(tagDTO.getParentTagId());
ext = buildExtParamByParentTag(tagDO);
+ } else {
+ ext = GsonUtils.getInstance().toJson(tagExt);
}
TagDO tagDO = TagDO.buildTagDO(tagDTO);
tagDO.setExt(ext);
+ tagDTO.setId(tagDO.getId());
return tagMapper.insert(tagDO);
}
@@ -120,7 +136,7 @@ public class TagServiceImpl implements TagService {
List<String> rootIds =
tagDOS.stream().map(TagDO::getId).collect(Collectors.toList());
List<TagDO> tagDOList = tagMapper.selectByParentTagIds(rootIds);
Map<String, Boolean> map = tagDOList.stream().collect(
- Collectors.toMap(TagDO::getParentTagId, tagDO -> true, (a, b) ->
b, ConcurrentHashMap::new));
+ Collectors.toMap(TagDO::getParentTagId, tagDO -> true, (a, b)
-> b, ConcurrentHashMap::new));
return tagDOS.stream().map(tag -> {
TagVO tagVO = TagVO.buildTagVO(tag);
if (map.get(tag.getId()) != null) {
@@ -138,7 +154,7 @@ public class TagServiceImpl implements TagService {
private void updateSubTags(final TagDTO tagDTO) {
List<TagDO> allData = tagMapper.selectByQuery(new TagQuery());
Map<String, TagDO> allDataMap = allData.stream().collect(
- Collectors.toMap(BaseDO::getId, Function.identity(), (a, b) -> b,
ConcurrentHashMap::new));
+ Collectors.toMap(BaseDO::getId, Function.identity(), (a, b) ->
b, ConcurrentHashMap::new));
TagDO update = TagDO.buildTagDO(tagDTO);
allDataMap.put(update.getId(), update);
Map<String, List<String>> relationMap = new ConcurrentHashMap<>();
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/LoadServiceDocEntryImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/LoadServiceDocEntryImpl.java
index 6b6971918..adaf6dba4 100755
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/LoadServiceDocEntryImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/LoadServiceDocEntryImpl.java
@@ -96,7 +96,7 @@ public class LoadServiceDocEntryImpl implements
LoadServiceDocEntry {
return;
}
final Set<UpstreamInstance> currentServices = new
HashSet<>(serviceList);
- LOG.info("load api document serviceList={}",
JsonUtils.toJson(currentServices));
+ LOG.info("load api document, serviceList={}",
JsonUtils.toJson(currentServices));
pullSwaggerDocService.pullApiDocument(currentServices);
}
@@ -112,7 +112,7 @@ public class LoadServiceDocEntryImpl implements
LoadServiceDocEntry {
return;
}
final Set<UpstreamInstance> currentServices = new
HashSet<>(serviceList);
- LOG.info("loadDocOnSelectorChanged serviceList={}",
JsonUtils.toJson(currentServices));
+ LOG.info("loadDocOnSelectorChanged, serviceList={}",
JsonUtils.toJson(currentServices));
pullSwaggerDocService.pullApiDocument(currentServices);
}
}
@@ -155,7 +155,7 @@ public class LoadServiceDocEntryImpl implements
LoadServiceDocEntry {
CommonPager<SelectorVO> commonPager = selectorService.listByPage(new
SelectorQuery(Lists.newArrayList(supportSwaggerPluginMap.keySet()), null, new
PageParameter(1, Integer.MAX_VALUE)));
List<SelectorVO> clusterList = commonPager.getDataList();
if (CollectionUtils.isEmpty(clusterList)) {
- LOG.info("getAllClusterLastUpdateInstanceList, Not loaded into
available backend services.");
+ LOG.info("getAllClusterLastUpdateInstanceList. Not loaded into
available backend services.");
return Collections.emptyList();
}
return clusterList.parallelStream()
@@ -174,7 +174,7 @@ public class LoadServiceDocEntryImpl implements
LoadServiceDocEntry {
private UpstreamInstance getClusterLastUpdateInstance(final SelectorData
selectorData) {
if (!supportSwaggerPluginMap.containsKey(selectorData.getPluginId())) {
- LOG.info("getClusterLastUpdateInstance. pluginNae={} does not
support pulling API documents.", selectorData.getPluginName());
+ LOG.info("getClusterLastUpdateInstance. pluginName={} does not
support pulling API documents.", selectorData.getPluginName());
return null;
}
List<UpstreamInstance> allInstances =
getInstances(selectorData.getPluginId(), selectorData.getHandle(),
selectorData.getName(), selectorData.getEnabled());
@@ -195,8 +195,7 @@ public class LoadServiceDocEntryImpl implements
LoadServiceDocEntry {
.orElse(null);
}
- private List<UpstreamInstance> getInstances(final String pluginId, final
String handle, final String contextPath,
- final boolean enabled) {
+ private List<UpstreamInstance> getInstances(final String pluginId, final
String handle, final String contextPath, final boolean enabled) {
List<UpstreamInstance> allInstances = null;
// Get service instance.
if (StringUtils.isNotEmpty(handle)) {
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/PullSwaggerDocServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/PullSwaggerDocServiceImpl.java
index b920b7db4..1f2606140 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/PullSwaggerDocServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/PullSwaggerDocServiceImpl.java
@@ -17,6 +17,8 @@
package org.apache.shenyu.admin.service.manager.impl;
+import com.google.common.collect.Interner;
+import com.google.common.collect.Interners;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -24,7 +26,9 @@ import java.util.Set;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
import org.apache.shenyu.admin.model.bean.UpstreamInstance;
+import org.apache.shenyu.admin.model.dto.TagDTO;
import org.apache.shenyu.admin.model.entity.TagDO;
import org.apache.shenyu.admin.model.vo.TagVO;
import org.apache.shenyu.admin.service.TagService;
@@ -32,7 +36,7 @@ import org.apache.shenyu.admin.service.manager.DocManager;
import org.apache.shenyu.admin.service.manager.PullSwaggerDocService;
import org.apache.shenyu.admin.utils.HttpUtils;
import org.apache.shenyu.common.constant.AdminConstants;
-import org.apache.shenyu.common.utils.JsonUtils;
+import org.apache.shenyu.common.utils.GsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@@ -48,7 +52,11 @@ public class PullSwaggerDocServiceImpl implements
PullSwaggerDocService {
private static final String SWAGGER_V2_PATH = "/v2/api-docs";
- private static final int PULL_MIN_INTERVAL_TIME = 30 * 1000;
+ private static final long PULL_MIN_INTERVAL_TIME = 30 * 1000;
+
+ private static final long DOC_LOCK_EXPIRED_TIME = 60 * 1000;
+
+ private final Interner<Object> interner = Interners.newWeakInterner();
@Resource
private DocManager docManager;
@@ -69,12 +77,15 @@ public class PullSwaggerDocServiceImpl implements
PullSwaggerDocService {
@Override
@SuppressWarnings("unchecked")
public void pullApiDocument(final UpstreamInstance instance) {
- TagVO tagVO = getTagVO(instance);
- TagDO.TagExt tagExt = Objects.nonNull(tagVO) ?
convertTagExt(tagVO.getExt()) : new TagDO.TagExt();
- if (!canPull(instance, tagExt.getRefreshTime())) {
- LOG.info("api document has been pulled and cannot be pulled
again,instance: {}", instance.getClusterName());
- return;
+ TagVO tagVO = null;
+ synchronized (interner.intern(instance.getClusterName())) {
+ tagVO = saveTagVOAndAcquireLock(instance);
+ if (!canPull(instance, tagVO)) {
+ LOG.info("api document has been pulled and cannot be pulled
again,instance: {}", instance.getClusterName());
+ return;
+ }
}
+ TagDO.TagExt tagExt = tagVO.getTagExt();
long newRefreshTime = System.currentTimeMillis();
String url = getSwaggerRequestUrl(instance);
try {
@@ -89,31 +100,66 @@ public class PullSwaggerDocServiceImpl implements
PullSwaggerDocService {
}
);
tagExt.setRefreshTime(newRefreshTime);
- //Save the time of the last updated document and the newMd5 of
apidoc.
- tagVO = Objects.nonNull(tagVO) ? tagVO : getTagVO(instance);
- if (Objects.nonNull(tagVO)) {
- tagService.updateTagExt(tagVO.getId(), tagExt);
- }
} catch (Exception e) {
LOG.error("add api document fail. clusterName={} url={} error={}",
instance.getClusterName(), url, e);
+ } finally {
+ tagExt.setDocLock(null);
+ //Save the time of the last updated document and the newMd5 of
apidoc.
+ tagService.updateTagExt(tagVO.getId(), tagExt);
}
}
- private boolean canPull(final UpstreamInstance instance, final Long
cacheLastStartUpTime) {
+ private boolean canPull(final UpstreamInstance instance, final TagVO
tagVO) {
boolean canPull = false;
+ if (Objects.isNull(tagVO) || Objects.isNull(tagVO.getTagExt()) ||
StringUtils.isEmpty(tagVO.getTagExt().getDocLock())) {
+ LOG.info("Unable to obtain lock for {}, retry after {} seconds.",
instance.getClusterName(), DOC_LOCK_EXPIRED_TIME / 1000);
+ return false;
+ }
+ Long cacheLastStartUpTime = tagVO.getTagExt().getRefreshTime();
if (Objects.isNull(cacheLastStartUpTime) || instance.getStartupTime()
> cacheLastStartUpTime + PULL_MIN_INTERVAL_TIME) {
canPull = true;
}
return canPull;
}
- private TagVO getTagVO(final UpstreamInstance instance) {
+ private TagVO saveTagVOAndAcquireLock(final UpstreamInstance instance) {
List<TagVO> tagVOList =
tagService.findByQuery(instance.getContextPath(),
AdminConstants.TAG_ROOT_PARENT_ID);
- return CollectionUtils.isNotEmpty(tagVOList) ? tagVOList.get(0) : null;
+ if (CollectionUtils.isNotEmpty(tagVOList)) {
+ TagVO tagVO = tagVOList.get(0);
+ TagDO.TagExt tagExt = convertTagExt(tagVO.getExt());
+ tagVO.setTagExt(tagExt);
+ if (StringUtils.isNotEmpty(tagExt.getDocLock()) &&
NumberUtils.toLong(tagExt.getDocLock(), 0) > System.currentTimeMillis()) {
+ tagExt.setDocLock(null);
+ return tagVO;
+ }
+ tagExt.setDocLock(this.generateDocLock());
+ tagService.updateTagExt(tagVO.getId(), tagExt);
+ return tagVO;
+ }
+ return createRootTagAndAcquireLock(instance);
+ }
+
+ private TagVO createRootTagAndAcquireLock(final UpstreamInstance instance)
{
+ TagDTO tagDTO = new TagDTO();
+ tagDTO.setTagDesc(instance.getClusterName());
+ tagDTO.setName(instance.getContextPath());
+ tagDTO.setParentTagId(AdminConstants.TAG_ROOT_PARENT_ID);
+ TagDO.TagExt tagExt = new TagDO.TagExt();
+ tagExt.setDocLock(this.generateDocLock());
+ tagService.createRootTag(tagDTO, tagExt);
+
+ TagVO tagVO = new TagVO();
+ tagVO.setId(tagDTO.getId());
+ tagVO.setTagExt(tagExt);
+ return tagVO;
+ }
+
+ private String generateDocLock() {
+ return String.valueOf(System.currentTimeMillis() +
DOC_LOCK_EXPIRED_TIME);
}
private TagDO.TagExt convertTagExt(final String ext) {
- return StringUtils.isNotEmpty(ext) ? JsonUtils.jsonToObject(ext,
TagDO.TagExt.class) : new TagDO.TagExt();
+ return StringUtils.isNotEmpty(ext) ?
GsonUtils.getInstance().fromJson(ext, TagDO.TagExt.class) : new TagDO.TagExt();
}
private String getSwaggerRequestUrl(final UpstreamInstance instance) {
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/RegisterApiDocServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/RegisterApiDocServiceImpl.java
index 334a04a7e..020988a3e 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/RegisterApiDocServiceImpl.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/manager/impl/RegisterApiDocServiceImpl.java
@@ -29,7 +29,6 @@ import org.apache.shenyu.admin.model.vo.TagVO;
import org.apache.shenyu.admin.service.ApiService;
import org.apache.shenyu.admin.service.TagService;
import org.apache.shenyu.admin.service.manager.RegisterApiDocService;
-import org.apache.shenyu.common.constant.AdminConstants;
import org.apache.shenyu.common.utils.UUIDUtils;
import org.apache.shenyu.register.common.dto.ApiDocRegisterDTO;
import org.apache.shenyu.register.common.enums.EventType;
@@ -69,9 +68,8 @@ public class RegisterApiDocServiceImpl implements
RegisterApiDocService {
String id = UUIDUtils.getInstance().generateShortUuid();
tagDTO.setTagDesc(tag);
tagDTO.setName(tag);
- tagDTO.setParentTagId(AdminConstants.TAG_ROOT_PARENT_ID);
tagDTO.setId(id);
- tagService.create(tagDTO);
+ tagService.createRootTag(tagDTO, null);
tagsIds.add(id);
}
}
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/ShenyuTestSwaggerApplication.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/ShenyuTestSwaggerApplication.java
index ccd141b3b..cb2b6ceef 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/ShenyuTestSwaggerApplication.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/ShenyuTestSwaggerApplication.java
@@ -21,7 +21,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
- * ShenyuTestHttpApplication.
+ * ShenyuTestSwaggerApplication.
*/
@SpringBootApplication
public class ShenyuTestSwaggerApplication {
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
index d2c2aef72..edc1c154e 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/HttpTestController.java
@@ -18,13 +18,16 @@
package org.apache.shenyu.examples.http.controller;
import com.google.common.collect.ImmutableMap;
+import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
+import java.util.Arrays;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.apache.shenyu.common.utils.GsonUtils;
import org.apache.shenyu.examples.http.dto.UserDTO;
import org.apache.shenyu.examples.http.result.ResultBean;
+import org.apache.shenyu.examples.http.result.TreeResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
@@ -64,6 +67,7 @@ import java.util.Map;
@RestController
@RequestMapping("/test")
@ShenyuSpringMvcClient("/test/**")
+@Api(tags = "HttpBaseTestAPI")
public class HttpTestController {
private static final Logger LOGGER =
LoggerFactory.getLogger(HttpTestController.class);
@@ -74,7 +78,7 @@ public class HttpTestController {
* @param userDTO the user dto
* @return the user dto
*/
- @ApiOperation(value = "payment", notes = "The user pays the order.")
+ @ApiOperation(value = "payment", notes = "The user pays the order.",
position = -100)
@PostMapping("/payment")
public UserDTO post(@RequestBody final UserDTO userDTO) {
return userDTO;
@@ -281,6 +285,7 @@ public class HttpTestController {
* @param requestParameter parameter
* @return result
*/
+ @ApiOperation(value = "modifyRequestWithHeaderAndCookie", notes = "modify
request with header and cookie.")
@PostMapping(path = "/modifyRequest")
public Map<String, Object> modifyRequest(@RequestBody final UserDTO
userDTO,
@CookieValue(value = "cookie", defaultValue = "") final String cookie,
@@ -294,6 +299,35 @@ public class HttpTestController {
return result;
}
+ /**
+ * Return Tree structure data.
+ *
+ * @param param param
+ * @return TreeResult
+ */
+ @ApiOperation(value = "retureTreeData", notes = "Return Tree structure
data.")
+ @PostMapping("/tree/v1")
+ public TreeResult tree(final UserDTO param) {
+ int id = 0;
+ TreeResult parent = new TreeResult();
+ parent.setId(++id);
+ parent.setName("parentNode" + param.getUserName());
+ parent.setParentId(0);
+
+ TreeResult child1 = new TreeResult();
+ child1.setId(++id);
+ child1.setName("childNode1");
+ child1.setParentId(1);
+
+ TreeResult child2 = new TreeResult();
+ child2.setId(++id);
+ child2.setName("childNode2");
+ child2.setParentId(1);
+
+ parent.setChildren(Arrays.asList(child1, child2));
+ return parent;
+ }
+
/**
* download file.
*
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OauthController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OauthController.java
index 7bfab2d44..be9c4f63e 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OauthController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OauthController.java
@@ -17,8 +17,6 @@
package org.apache.shenyu.examples.http.controller;
-import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
-import org.apache.shenyu.client.apidocs.annotations.ApiModule;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,7 +28,6 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/oauth")
@ShenyuSpringMvcClient("/oauth")
-@ApiModule(value = "oauth")
public class OauthController {
/**
@@ -39,7 +36,6 @@ public class OauthController {
* @return String
*/
@GetMapping("/authorize")
- @ApiDoc(desc = "authorize")
public String testCode() {
return "authorize";
}
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OrderController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OrderController.java
index 1a3ee45e6..a96380ce3 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OrderController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/OrderController.java
@@ -38,7 +38,7 @@ import java.util.Objects;
/**
* TestController.
*/
-@Api(tags = "Order API")
+@Api(tags = "Order API", position = 2)
@RestController
@RequestMapping("/order")
@ShenyuSpringMvcClient("/order")
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/RequestController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/RequestController.java
index b61229001..22b8539a9 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/RequestController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/RequestController.java
@@ -17,6 +17,7 @@
package org.apache.shenyu.examples.http.controller;
+import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.slf4j.Logger;
@@ -34,6 +35,7 @@ import reactor.core.publisher.Mono;
/**
* RequestController.
*/
+@Api(tags = "RequestController", position = 1)
@RestController
@RequestMapping("/request")
@ShenyuSpringMvcClient("/request/**")
@@ -48,7 +50,7 @@ public class RequestController {
* @param serverHttpRequest request
* @return response
*/
- @ApiOperation(value = "header", notes = "test request header.")
+ @ApiOperation(value = "testRequestHeader", notes = "test request header.")
@GetMapping(path = "/header")
public Mono<String> testRequestHeader(@RequestHeader("header_key1") final
String headerKey1,
final ServerHttpRequest serverHttpRequest) {
@@ -63,7 +65,7 @@ public class RequestController {
* @param serverHttpRequest request
* @return response
*/
- @ApiOperation(value = "parameter", notes = "test request parameter.")
+ @ApiOperation(value = "testRequestParameter", notes = "test request
parameter.")
@PostMapping(path = "/parameter")
public Mono<String> testRequestParameter(@RequestParam("parameter_key1")
final String parameterKey1,
final ServerHttpRequest serverHttpRequest) {
@@ -78,6 +80,7 @@ public class RequestController {
* @param serverHttpRequest request
* @return response
*/
+ @ApiOperation(value = "testRequestCookie", notes = "test request
parameter.")
@GetMapping(path = "/cookie")
public Mono<String> testRequestCookie(@CookieValue("userId") final String
userId,
final ServerHttpRequest serverHttpRequest) {
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/SpringMvcMappingPathController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/SpringMvcMappingPathController.java
index 5bf9a0b09..15130d842 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/SpringMvcMappingPathController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/SpringMvcMappingPathController.java
@@ -17,8 +17,8 @@
package org.apache.shenyu.examples.http.controller;
-import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
-import org.apache.shenyu.client.apidocs.annotations.ApiModule;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController;
*/
@RestController
@ShenyuSpringMvcClient(desc = "spring annotation register")
-@ApiModule(value = "springMvcMappingPathController")
+@Api(value = "springMvcMappingPathController")
public class SpringMvcMappingPathController {
private static final String HELLO_SUFFIX = "I'm Shenyu-Gateway System.
Welcome!";
@@ -40,7 +40,7 @@ public class SpringMvcMappingPathController {
* @return result
*/
@RequestMapping("hello")
- @ApiDoc(desc = "hello")
+ @ApiOperation(value = "hello", notes = "say hello.")
public String hello() {
return "hello! " + HELLO_SUFFIX;
}
@@ -52,7 +52,7 @@ public class SpringMvcMappingPathController {
* @return result
*/
@RequestMapping("hi")
- @ApiDoc(desc = "hi")
+ @ApiOperation(value = "hi", notes = "say hello to name.")
public String hello(final String name) {
return "hi! " + name + "! " + HELLO_SUFFIX;
}
@@ -64,7 +64,7 @@ public class SpringMvcMappingPathController {
* @return result
*/
@PostMapping("post/hi")
- @ApiDoc(desc = "post/hi")
+ @ApiOperation(value = "postHi", notes = "post hi.")
public String post(final String name) {
return "[post method result]:hi! " + name + "! " + HELLO_SUFFIX;
}
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/UploadController.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/UploadController.java
index b81e73b40..93d1e9a2b 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/UploadController.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/controller/UploadController.java
@@ -17,9 +17,9 @@
package org.apache.shenyu.examples.http.controller;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
import java.util.stream.Collectors;
-import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
-import org.apache.shenyu.client.apidocs.annotations.ApiModule;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
@@ -36,7 +36,7 @@ import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/upload")
@ShenyuSpringMvcClient("/upload/**")
-@ApiModule(value = "upload")
+@Api(tags = "upload api")
public class UploadController {
/**
@@ -46,7 +46,7 @@ public class UploadController {
* @return response
*/
@PostMapping(value = "/webFluxSingle", consumes =
{MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.TEXT_PLAIN_VALUE})
- @ApiDoc(desc = "webFluxSingle")
+ @ApiOperation(value = "webFluxSingle", notes = "upload webFluxSingle.")
public Mono<String> webFluxSingle(@RequestPart("file") final FilePart
file) {
return Mono.just(file.filename());
}
@@ -58,7 +58,7 @@ public class UploadController {
* @return response
*/
@PostMapping(value = "/webFluxFiles", consumes =
{MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.TEXT_PLAIN_VALUE})
- @ApiDoc(desc = "webFluxFiles")
+ @ApiOperation(value = "webFluxFiles", notes = "upload webFluxFiles.")
public Mono<String> webFluxFiles(@RequestPart(value = "files", required =
false) final Flux<FilePart> files) {
return files.map(FilePart::filename).collect(Collectors.joining(","));
}
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
index 160f85478..6f1024659 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.examples.http.dto;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
+import java.util.Date;
import java.util.StringJoiner;
/**
@@ -32,6 +33,9 @@ public class OrderDTO implements Serializable {
@ApiModelProperty(value = "name", required = true, example = "jack")
private String name;
+ @ApiModelProperty(value = "createTime", example = "2023-08-01 10:10:01")
+ private Date createTime;
+
/**
* Get id.
*
@@ -68,11 +72,28 @@ public class OrderDTO implements Serializable {
this.name = name;
}
+ /**
+ * get createTime.
+ * @return createTime
+ */
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ /**
+ * setCreateTime.
+ * @param createTime createTime
+ */
+ public void setCreateTime(final Date createTime) {
+ this.createTime = createTime;
+ }
+
@Override
public String toString() {
return new StringJoiner(", ", OrderDTO.class.getSimpleName() + "[",
"]")
.add("id='" + id + "'")
.add("name='" + name + "'")
+ .add("createTime='" + createTime + "'")
.toString();
}
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/RequestDTO.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/RequestDTO.java
index 8dbcb0a00..ab506d8e6 100644
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/RequestDTO.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/RequestDTO.java
@@ -28,13 +28,13 @@ public class RequestDTO {
@ApiModelProperty(value = "module", required = true, example =
"usercenter")
private String module;
- @ApiModelProperty(value = "method", required = true, example =
"findByUserId")
+ @ApiModelProperty(value = "method", required = true, example =
"findByUserId", position = 1)
private String method;
@ApiModelProperty(value = "content", example = "hello,shenyu")
private String content;
- @ApiModelProperty(value = "extInfo", example = "extended information")
+ @ApiModelProperty(value = "extInfo", example = "extended information",
position = 2)
private String extInfo;
public RequestDTO() {
diff --git
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/result/TreeResult.java
old mode 100644
new mode 100755
similarity index 55%
copy from
shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
copy to
shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/result/TreeResult.java
index 160f85478..c5f7f831e
---
a/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/dto/OrderDTO.java
+++
b/shenyu-examples/shenyu-examples-http-swagger2/src/main/java/org/apache/shenyu/examples/http/result/TreeResult.java
@@ -15,43 +15,44 @@
* limitations under the License.
*/
-package org.apache.shenyu.examples.http.dto;
+package org.apache.shenyu.examples.http.result;
import io.swagger.annotations.ApiModelProperty;
-import java.io.Serializable;
-import java.util.StringJoiner;
+import java.util.List;
-/**
- * The type Order dto.
- */
-public class OrderDTO implements Serializable {
-
- @ApiModelProperty(value = "id", required = true, example = "100000")
- private String id;
+public class TreeResult {
+ @ApiModelProperty(value = "id", required = true, example = "123")
+ private Integer id;
- @ApiModelProperty(value = "name", required = true, example = "jack")
+ @ApiModelProperty(value = "name", required = true, example = "shenyu")
private String name;
+ @ApiModelProperty(value = "parent id")
+ private Integer parentId;
+
+ @ApiModelProperty(value = "children node list", example = "list")
+ private List<TreeResult> children;
+
/**
- * Get id.
+ * get id.
*
- * @return id
+ * @return Integer
*/
- public String getId() {
+ public Integer getId() {
return id;
}
/**
- * Set id.
+ * setId.
*
* @param id id
*/
- public void setId(final String id) {
+ public void setId(final Integer id) {
this.id = id;
}
/**
- * Get name.
+ * get name.
*
* @return name
*/
@@ -60,7 +61,7 @@ public class OrderDTO implements Serializable {
}
/**
- * Set name.
+ * setName.
*
* @param name name
*/
@@ -68,12 +69,39 @@ public class OrderDTO implements Serializable {
this.name = name;
}
- @Override
- public String toString() {
- return new StringJoiner(", ", OrderDTO.class.getSimpleName() + "[",
"]")
- .add("id='" + id + "'")
- .add("name='" + name + "'")
- .toString();
+ /**
+ * getParentId.
+ *
+ * @return parentId
+ */
+ public Integer getParentId() {
+ return parentId;
}
+ /**
+ * setParentId.
+ *
+ * @param parentId parentId
+ */
+ public void setParentId(final Integer parentId) {
+ this.parentId = parentId;
+ }
+
+ /**
+ * getChildren.
+ *
+ * @return list
+ */
+ public List<TreeResult> getChildren() {
+ return children;
+ }
+
+ /**
+ * setChildren.
+ *
+ * @param children children
+ */
+ public void setChildren(final List<TreeResult> children) {
+ this.children = children;
+ }
}