This is an automated email from the ASF dual-hosted git repository.
zhangzicheng 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 16a7266fe [ISSUE #4029] apidoc stage2: api-crud (#4137)
16a7266fe is described below
commit 16a7266fe5cdfca6b1f29b29254d04a807d57457
Author: zhengpeng <[email protected]>
AuthorDate: Fri Nov 4 11:30:26 2022 +0800
[ISSUE #4029] apidoc stage2: api-crud (#4137)
* #4029 api crud
* #4029 api crud some unit test
* #4029 api crud and unit test
* #4029 api page query and detail return add tags
* #4029 api add tagId
* #4029 api state byte change to Integer
* #4029 fix api crud
Co-authored-by: dragon-zhang <[email protected]>
---
.../shenyu/admin/controller/ApiController.java | 140 ++++
.../org/apache/shenyu/admin/mapper/ApiMapper.java | 40 +-
.../org/apache/shenyu/admin/mapper/TagMapper.java | 10 +-
.../shenyu/admin/mapper/TagRelationMapper.java | 21 +
.../model/{entity/ApiDO.java => dto/ApiDTO.java} | 104 ++-
.../apache/shenyu/admin/model/entity/ApiDO.java | 295 +++++++-
.../apache/shenyu/admin/model/query/ApiQuery.java | 152 ++++
.../shenyu/admin/model/query/TagRelationQuery.java | 55 ++
.../org/apache/shenyu/admin/model/vo/ApiVO.java | 790 +++++++++++++++++++++
.../apache/shenyu/admin/service/ApiService.java | 65 ++
.../shenyu/admin/service/impl/ApiServiceImpl.java | 179 +++++
.../src/main/resources/mappers/api-sqlmap.xml | 61 ++
.../main/resources/mappers/tag-relation-sqlmap.xml | 31 +
.../src/main/resources/mappers/tag-sqlmap.xml | 12 +-
.../shenyu/admin/controller/ApiControllerTest.java | 196 +++++
.../apache/shenyu/admin/mapper/ApiMapperTest.java | 6 +-
.../shenyu/admin/service/ApiServiceTest.java | 175 +++++
.../shenyu/common/constant/AdminConstants.java | 5 +
18 files changed, 2321 insertions(+), 16 deletions(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ApiController.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ApiController.java
new file mode 100644
index 000000000..e26f4aa45
--- /dev/null
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ApiController.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.controller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.mapper.ApiMapper;
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.admin.model.page.CommonPager;
+import org.apache.shenyu.admin.model.page.PageParameter;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
+import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.service.ApiService;
+import org.apache.shenyu.admin.utils.ShenyuResultMessage;
+import org.apache.shenyu.admin.validation.annotation.Existed;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * this is api controller.
+ */
+@Validated
+@RestController
+@RequestMapping("/api")
+public class ApiController {
+
+ private final ApiService apiService;
+
+ public ApiController(final ApiService apiService) {
+ this.apiService = apiService;
+ }
+
+ /**
+ * query apis.
+ *
+ * @param apiPath api path.
+ * @param state state.
+ * @param tagId tagId.
+ * @param currentPage current page.
+ * @param pageSize page size.
+ * @return {@linkplain ShenyuAdminResult}
+ */
+ @GetMapping("")
+ public ShenyuAdminResult queryApis(final String apiPath, final Integer
state,
+ final String tagId,
+ @NotNull final Integer currentPage,
+ @NotNull final Integer pageSize) {
+ CommonPager<ApiVO> commonPager = apiService.listByPage(new
ApiQuery(apiPath, state, tagId, new PageParameter(currentPage, pageSize)));
+ return ShenyuAdminResult.success(ShenyuResultMessage.QUERY_SUCCESS,
commonPager);
+ }
+
+ /**
+ * detail plugin.
+ *
+ * @param id plugin id.
+ * @return {@linkplain ShenyuAdminResult}
+ */
+ @GetMapping("/{id}")
+ public ShenyuAdminResult detailApi(@PathVariable("id")
+ @Existed(message = "api is not existed",
+ provider = ApiMapper.class)
final String id) {
+ ApiVO apiVO = apiService.findById(id);
+ return ShenyuAdminResult.success(ShenyuResultMessage.DETAIL_SUCCESS,
apiVO);
+ }
+
+ /**
+ * create api.
+ *
+ * @param apiDTO api.
+ * @return {@linkplain ShenyuAdminResult}
+ */
+ @PostMapping("")
+ @RequiresPermissions("system:api:add")
+ public ShenyuAdminResult createApi(@Valid @RequestBody final ApiDTO
apiDTO) {
+ return ShenyuAdminResult.success(apiService.createOrUpdate(apiDTO));
+ }
+
+ /**
+ * update api.
+ *
+ * @param id primary key.
+ * @param apiDTO api.
+ * @return {@linkplain ShenyuAdminResult}
+ */
+ @PutMapping("/{id}")
+ @RequiresPermissions("system:api:edit")
+ public ShenyuAdminResult updateApi(@PathVariable("id")
+ @Existed(message = "api is not existed",
+ provider = ApiMapper.class)
final String id,
+ @Valid @RequestBody final ApiDTO
apiDTO) {
+ apiDTO.setId(id);
+ return createApi(apiDTO);
+ }
+
+ /**
+ * delete apis.
+ *
+ * @param ids primary key.
+ * @return {@linkplain ShenyuAdminResult}
+ */
+ @DeleteMapping("/batch")
+ @RequiresPermissions("system:api:delete")
+ public ShenyuAdminResult deleteApis(@RequestBody @NotEmpty final
List<@NotBlank String> ids) {
+ final String result = apiService.delete(ids);
+ if (StringUtils.isNoneBlank(result)) {
+ return ShenyuAdminResult.error(result);
+ }
+ return ShenyuAdminResult.success(ShenyuResultMessage.DELETE_SUCCESS);
+ }
+
+}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ApiMapper.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ApiMapper.java
index aa81911e8..ea1b44d71 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ApiMapper.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/ApiMapper.java
@@ -18,13 +18,19 @@
package org.apache.shenyu.admin.mapper;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import org.apache.shenyu.admin.model.entity.ApiDO;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.validation.ExistProvider;
+
+import java.io.Serializable;
+import java.util.List;
/**
* ApiMapper.
**/
@Mapper
-public interface ApiMapper {
+public interface ApiMapper extends ExistProvider {
/**
* delete by primary key.
*
@@ -72,4 +78,36 @@ public interface ApiMapper {
* @return update count
*/
int updateByPrimaryKey(ApiDO record);
+
+ /**
+ * existed.
+ *
+ * @param id id
+ * @return existed
+ */
+ @Override
+ Boolean existed(@Param("id") Serializable id);
+
+ /**
+ * select api by query.
+ *
+ * @param query {@linkplain ApiQuery}
+ * @return {@linkplain List}
+ */
+ List<ApiDO> selectByQuery(ApiQuery query);
+
+ /**
+ * select api by ids.
+ * @param ids primary keys.
+ * @return {@linkplain ApiDO}
+ */
+ List<ApiDO> selectByIds(List<String> ids);
+
+ /**
+ * delete api.
+ *
+ * @param ids primary keys.
+ * @return rows int
+ */
+ int deleteByIds(List<String> ids);
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagMapper.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagMapper.java
index 72aec4172..d042666dd 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagMapper.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagMapper.java
@@ -17,12 +17,13 @@
package org.apache.shenyu.admin.mapper;
-import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.shenyu.admin.model.entity.TagDO;
import org.apache.shenyu.admin.model.query.TagQuery;
import org.apache.shenyu.admin.validation.ExistProvider;
+import java.util.List;
+
/**
* this is User Tag Mapper.
*/
@@ -105,4 +106,11 @@ public interface TagMapper extends ExistProvider {
* @return delete count
*/
int deleteAllData();
+
+ /**
+ * selectByIds.
+ * @param list ids
+ * @return List
+ */
+ List<TagDO> selectByIds(List<String> list);
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagRelationMapper.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagRelationMapper.java
index c113f2631..78d1d415f 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagRelationMapper.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/mapper/TagRelationMapper.java
@@ -19,6 +19,7 @@ package org.apache.shenyu.admin.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import org.apache.shenyu.admin.model.entity.TagRelationDO;
import org.apache.shenyu.admin.model.query.TagRelationQuery;
import org.apache.shenyu.admin.validation.ExistProvider;
@@ -93,5 +94,25 @@ public interface TagRelationMapper extends ExistProvider {
*/
int updateByPrimaryKey(TagRelationDO record);
+ /**
+ * batchInsert.
+ * @param list list
+ * @return insert rows
+ */
+ int batchInsert(@Param(value = "list") List<TagRelationDO> list);
+
+ /**
+ * deleteByApiId.
+ * @param apiId apiId
+ * @return delete rows
+ */
+ int deleteByApiId(@Param(value = "apiId") String apiId);
+
+ /**
+ * deleteByApiIds.
+ * @param apiIds apiIds
+ * @return delete rows
+ */
+ int deleteByApiIds(@Param(value = "apiIds") List<String> apiIds);
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/ApiDTO.java
similarity index 73%
copy from
shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
copy to shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/ApiDTO.java
index b490cd05d..1789cbac2 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/dto/ApiDTO.java
@@ -15,17 +15,27 @@
* limitations under the License.
*/
-package org.apache.shenyu.admin.model.entity;
+package org.apache.shenyu.admin.model.dto;
+import org.apache.shenyu.admin.mapper.ApiMapper;
+import org.apache.shenyu.admin.validation.annotation.Existed;
+
+import java.io.Serializable;
import java.util.Date;
+import java.util.List;
+import java.util.Objects;
/**
- * api.
+ * this is api from by web front.
*/
-public class ApiDO {
+public class ApiDTO implements Serializable {
+
+ private static final long serialVersionUID = -1859047620316026098L;
+
/**
* primary key id.
*/
+ @Existed(provider = ApiMapper.class, nullOfIgnore = true, message = "the
api is not exited")
private String id;
/**
@@ -66,7 +76,7 @@ public class ApiDO {
/**
* 0-unpublished1-published2-offline.
*/
- private Byte state;
+ private Integer state;
/**
* extended fields.
@@ -108,8 +118,14 @@ public class ApiDO {
*/
private Date dateUpdated;
+ /**
+ * tagIds.
+ */
+ private List<String> tagIds;
+
/**
* getId.
+ *
* @return id
*/
public String getId() {
@@ -118,6 +134,7 @@ public class ApiDO {
/**
* set id.
+ *
* @param id id
*/
public void setId(final String id) {
@@ -126,6 +143,7 @@ public class ApiDO {
/**
* getContextPath.
+ *
* @return context path
*/
public String getContextPath() {
@@ -134,6 +152,7 @@ public class ApiDO {
/**
* set context path.
+ *
* @param contextPath context path
*/
public void setContextPath(final String contextPath) {
@@ -142,6 +161,7 @@ public class ApiDO {
/**
* getApiPath.
+ *
* @return apiPath
*/
public String getApiPath() {
@@ -150,6 +170,7 @@ public class ApiDO {
/**
* setApiPath.
+ *
* @param apiPath apiPath
*/
public void setApiPath(final String apiPath) {
@@ -158,6 +179,7 @@ public class ApiDO {
/**
* getHttpMethod.
+ *
* @return http method
*/
public Integer getHttpMethod() {
@@ -166,6 +188,7 @@ public class ApiDO {
/**
* setHttpMethod.
+ *
* @param httpMethod http method
*/
public void setHttpMethod(final Integer httpMethod) {
@@ -174,6 +197,7 @@ public class ApiDO {
/**
* getConsume.
+ *
* @return consume
*/
public String getConsume() {
@@ -182,6 +206,7 @@ public class ApiDO {
/**
* setConsume.
+ *
* @param consume consume
*/
public void setConsume(final String consume) {
@@ -190,6 +215,7 @@ public class ApiDO {
/**
* getProduce.
+ *
* @return produce
*/
public String getProduce() {
@@ -198,6 +224,7 @@ public class ApiDO {
/**
* setProduce.
+ *
* @param produce the produce
*/
public void setProduce(final String produce) {
@@ -206,6 +233,7 @@ public class ApiDO {
/**
* getVersion.
+ *
* @return version
*/
public String getVersion() {
@@ -214,6 +242,7 @@ public class ApiDO {
/**
* setVersion.
+ *
* @param version the version
*/
public void setVersion(final String version) {
@@ -222,6 +251,7 @@ public class ApiDO {
/**
* getRpcType.
+ *
* @return rpc type
*/
public String getRpcType() {
@@ -230,6 +260,7 @@ public class ApiDO {
/**
* setRpcType.
+ *
* @param rpcType the rpc type
*/
public void setRpcType(final String rpcType) {
@@ -238,23 +269,26 @@ public class ApiDO {
/**
* getState.
+ *
* @return state
*/
- public Byte getState() {
+ public Integer getState() {
return state;
}
/**
* setState.
+ *
* @param state state
*/
- public void setState(final Byte state) {
+ public void setState(final Integer state) {
this.state = state;
}
/**
* getExt.
- * @return extension.
+ *
+ * @return extension.
*/
public String getExt() {
return ext;
@@ -262,6 +296,7 @@ public class ApiDO {
/**
* setExt.
+ *
* @param ext extension
*/
public void setExt(final String ext) {
@@ -270,6 +305,7 @@ public class ApiDO {
/**
* getApiOwner.
+ *
* @return apiOwner
*/
public String getApiOwner() {
@@ -278,6 +314,7 @@ public class ApiDO {
/**
* setApiOwner.
+ *
* @param apiOwner apiOwner
*/
public void setApiOwner(final String apiOwner) {
@@ -286,6 +323,7 @@ public class ApiDO {
/**
* getApiDesc.
+ *
* @return apiDesc
*/
public String getApiDesc() {
@@ -294,6 +332,7 @@ public class ApiDO {
/**
* setApiDesc.
+ *
* @param apiDesc apiDesc
*/
public void setApiDesc(final String apiDesc) {
@@ -302,6 +341,7 @@ public class ApiDO {
/**
* getApiSource.
+ *
* @return apiSource
*/
public Integer getApiSource() {
@@ -310,6 +350,7 @@ public class ApiDO {
/**
* setSource.
+ *
* @param apiSource apiSource
*/
public void setApiSource(final Integer apiSource) {
@@ -318,6 +359,7 @@ public class ApiDO {
/**
* getDocument.
+ *
* @return document
*/
public String getDocument() {
@@ -326,6 +368,7 @@ public class ApiDO {
/**
* setDocument.
+ *
* @param document document
*/
public void setDocument(final String document) {
@@ -334,6 +377,7 @@ public class ApiDO {
/**
* getDocumentMd5.
+ *
* @return document md5
*/
public String getDocumentMd5() {
@@ -342,6 +386,7 @@ public class ApiDO {
/**
* setDocumentMd5.
+ *
* @param documentMd5 documentMd5
*/
public void setDocumentMd5(final String documentMd5) {
@@ -350,6 +395,7 @@ public class ApiDO {
/**
* getDateCreated.
+ *
* @return dateCreated
*/
public Date getDateCreated() {
@@ -358,6 +404,7 @@ public class ApiDO {
/**
* setDateCreated.
+ *
* @param dateCreated dateCreated
*/
public void setDateCreated(final Date dateCreated) {
@@ -366,6 +413,7 @@ public class ApiDO {
/**
* getDateUpdated.
+ *
* @return dateUpdated
*/
public Date getDateUpdated() {
@@ -374,9 +422,51 @@ public class ApiDO {
/**
* setDateUpdated.
+ *
* @param dateUpdated dateUpdated
*/
public void setDateUpdated(final Date dateUpdated) {
this.dateUpdated = dateUpdated;
}
+
+ /**
+ * getTagIds.
+ *
+ * @return tagIds
+ */
+ public List<String> getTagIds() {
+ return tagIds;
+ }
+
+ /**
+ * setTagIds.
+ *
+ * @param tagIds tagIds
+ */
+ public void setTagIds(final List<String> tagIds) {
+ this.tagIds = tagIds;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ApiDTO)) {
+ return false;
+ }
+ ApiDTO apiDTO = (ApiDTO) o;
+ return Objects.equals(id, apiDTO.id) && Objects.equals(contextPath,
apiDTO.contextPath) && Objects.equals(apiPath, apiDTO.apiPath) &&
Objects.equals(httpMethod, apiDTO.httpMethod)
+ && Objects.equals(consume, apiDTO.consume) &&
Objects.equals(produce, apiDTO.produce) && Objects.equals(version,
apiDTO.version) && Objects.equals(rpcType, apiDTO.rpcType)
+ && Objects.equals(state, apiDTO.state) && Objects.equals(ext,
apiDTO.ext) && Objects.equals(apiOwner, apiDTO.apiOwner) &&
Objects.equals(apiDesc, apiDTO.apiDesc)
+ && Objects.equals(apiSource, apiDTO.apiSource) &&
Objects.equals(document, apiDTO.document) && Objects.equals(documentMd5,
apiDTO.documentMd5)
+ && Objects.equals(dateCreated, apiDTO.dateCreated) &&
Objects.equals(dateUpdated, apiDTO.dateUpdated) && Objects.equals(tagIds,
apiDTO.tagIds);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, contextPath, apiPath, httpMethod, consume,
produce, version,
+ rpcType, state, ext, apiOwner, apiDesc, apiSource, document,
documentMd5, dateCreated, dateUpdated, tagIds);
+ }
+
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
index b490cd05d..c85fce995 100644
--- a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/ApiDO.java
@@ -17,7 +17,14 @@
package org.apache.shenyu.admin.model.entity;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.common.utils.UUIDUtils;
+
+import java.sql.Timestamp;
import java.util.Date;
+import java.util.Optional;
/**
* api.
@@ -66,7 +73,7 @@ public class ApiDO {
/**
* 0-unpublished1-published2-offline.
*/
- private Byte state;
+ private Integer state;
/**
* extended fields.
@@ -240,7 +247,7 @@ public class ApiDO {
* getState.
* @return state
*/
- public Byte getState() {
+ public Integer getState() {
return state;
}
@@ -248,7 +255,7 @@ public class ApiDO {
* setState.
* @param state state
*/
- public void setState(final Byte state) {
+ public void setState(final Integer state) {
this.state = state;
}
@@ -379,4 +386,286 @@ public class ApiDO {
public void setDateUpdated(final Date dateUpdated) {
this.dateUpdated = dateUpdated;
}
+
+ /**
+ * builder.
+ * @return ApiDOBuilder
+ */
+ public static ApiDOBuilder builder() {
+ return new ApiDOBuilder();
+ }
+
+ /**
+ * buildApiDO.
+ * @param apiDTO apiDTO
+ * @return ApiDO
+ */
+ public static ApiDO buildApiDO(final ApiDTO apiDTO) {
+
+ return Optional.ofNullable(apiDTO).map(item -> {
+ Timestamp currentTime = new Timestamp(System.currentTimeMillis());
+ ApiDO apiDO = ApiDO.builder()
+ .contextPath(item.getContextPath())
+ .apiPath(item.getApiPath())
+ .httpMethod(item.getHttpMethod())
+ .consume(item.getConsume())
+ .produce(item.getProduce())
+ .version(item.getVersion())
+ .rpcType(item.getRpcType())
+ .state(item.getState())
+ .ext(item.getExt())
+ .apiOwner(item.getApiOwner())
+ .apiDesc(item.getApiDesc())
+ .apiSource(item.getApiSource())
+ .document(item.getDocument())
+ .documentMd5(DigestUtils.md5Hex(item.getDocument()))
+ .build();
+ if (StringUtils.isEmpty(item.getId())) {
+ apiDO.setId(UUIDUtils.getInstance().generateShortUuid());
+ apiDO.setDateCreated(currentTime);
+ } else {
+ apiDO.setId(item.getId());
+ }
+ return apiDO;
+ }).orElse(null);
+ }
+
+ public static final class ApiDOBuilder {
+
+ private String id;
+
+ private String contextPath;
+
+ private String apiPath;
+
+ private Integer httpMethod;
+
+ private String consume;
+
+ private String produce;
+
+ private String version;
+
+ private String rpcType;
+
+ private Integer state;
+
+ private String ext;
+
+ private String apiOwner;
+
+ private String apiDesc;
+
+ private Integer apiSource;
+
+ private String document;
+
+ private String documentMd5;
+
+ private Date dateCreated;
+
+ private Date dateUpdated;
+
+ /**
+ * Construct.
+ */
+ private ApiDOBuilder() {
+ }
+
+ /**
+ * builder id.
+ * @param id id
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder id(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * builder contextPath.
+ * @param contextPath contextPath
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder contextPath(final String contextPath) {
+ this.contextPath = contextPath;
+ return this;
+ }
+
+ /**
+ * builder apiPath.
+ * @param apiPath apiPath
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder apiPath(final String apiPath) {
+ this.apiPath = apiPath;
+ return this;
+ }
+
+ /**
+ * builder httpMethod.
+ * @param httpMethod httpMethod
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder httpMethod(final Integer httpMethod) {
+ this.httpMethod = httpMethod;
+ return this;
+ }
+
+ /**
+ * builder httpMethod.
+ * @param consume consume
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder consume(final String consume) {
+ this.consume = consume;
+ return this;
+ }
+
+ /**
+ * builder produce.
+ * @param produce produce
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder produce(final String produce) {
+ this.produce = produce;
+ return this;
+ }
+
+ /**
+ * builder version.
+ * @param version version
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder version(final String version) {
+ this.version = version;
+ return this;
+ }
+
+ /**
+ * builder rpcType.
+ * @param rpcType rpcType
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder rpcType(final String rpcType) {
+ this.rpcType = rpcType;
+ return this;
+ }
+
+ /**
+ * builder state.
+ * @param state state
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder state(final Integer state) {
+ this.state = state;
+ return this;
+ }
+
+ /**
+ * builder ext.
+ * @param ext ext
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder ext(final String ext) {
+ this.ext = ext;
+ return this;
+ }
+
+ /**
+ * builder apiOwner.
+ * @param apiOwner apiOwner
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder apiOwner(final String apiOwner) {
+ this.apiOwner = apiOwner;
+ return this;
+ }
+
+ /**
+ * builder apiDesc.
+ * @param apiDesc apiDesc
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder apiDesc(final String apiDesc) {
+ this.apiDesc = apiDesc;
+ return this;
+ }
+
+ /**
+ * builder apiSource.
+ * @param apiSource apiSource
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder apiSource(final Integer apiSource) {
+ this.apiSource = apiSource;
+ return this;
+ }
+
+ /**
+ * builder document.
+ * @param document document
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder document(final String document) {
+ this.document = document;
+ return this;
+ }
+
+ /**
+ * builder documentMd5.
+ * @param documentMd5 documentMd5
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder documentMd5(final String documentMd5) {
+ this.documentMd5 = documentMd5;
+ return this;
+ }
+
+ /**
+ * builder dateCreated.
+ * @param dateCreated dateCreated
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder dateCreated(final Date dateCreated) {
+ this.dateCreated = dateCreated;
+ return this;
+ }
+
+ /**
+ * builder dateUpdated.
+ * @param dateUpdated dateUpdated
+ * @return ApiDOBuilder
+ */
+ public ApiDOBuilder dateUpdated(final Date dateUpdated) {
+ this.dateUpdated = dateUpdated;
+ return this;
+ }
+
+ /**
+ * builder.
+ * @return ApiDO
+ */
+ public ApiDO build() {
+ ApiDO apiDO = new ApiDO();
+ apiDO.setId(id);
+ apiDO.setContextPath(contextPath);
+ apiDO.setApiPath(apiPath);
+ apiDO.setHttpMethod(httpMethod);
+ apiDO.setConsume(consume);
+ apiDO.setProduce(produce);
+ apiDO.setVersion(version);
+ apiDO.setRpcType(rpcType);
+ apiDO.setState(state);
+ apiDO.setExt(ext);
+ apiDO.setApiOwner(apiOwner);
+ apiDO.setApiDesc(apiDesc);
+ apiDO.setApiSource(apiSource);
+ apiDO.setDocument(document);
+ apiDO.setDocumentMd5(documentMd5);
+ apiDO.setDateCreated(dateCreated);
+ apiDO.setDateUpdated(dateUpdated);
+ return apiDO;
+ }
+ }
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/ApiQuery.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/ApiQuery.java
new file mode 100644
index 000000000..144fcba06
--- /dev/null
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/ApiQuery.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.model.query;
+
+import org.apache.shenyu.admin.model.page.PageParameter;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * this is plugin query.
+ */
+public class ApiQuery implements Serializable {
+
+ private static final long serialVersionUID = 167659024501717438L;
+
+ /**
+ * apiPath.
+ */
+ private String apiPath;
+
+
+ /**
+ * state.
+ */
+ private Integer state;
+
+
+ /**
+ * tagId.
+ */
+ private String tagId;
+
+ /**
+ * page parameter.
+ */
+ private PageParameter pageParameter;
+
+ public ApiQuery() {
+ }
+
+ public ApiQuery(final String apiPath, final Integer state, final String
tagId, final PageParameter pageParameter) {
+ this.apiPath = apiPath;
+ this.state = state;
+ this.tagId = tagId;
+ this.pageParameter = pageParameter;
+ }
+
+ /**
+ * get apiPath.
+ *
+ * @return apiPath
+ */
+ public String getApiPath() {
+ return apiPath;
+ }
+
+ /**
+ * set apiPath.
+ *
+ * @param apiPath apiPath
+ */
+ public void setApiPath(final String apiPath) {
+ this.apiPath = apiPath;
+ }
+
+ /**
+ * get state.
+ *
+ * @return state
+ */
+ public Integer getState() {
+ return state;
+ }
+
+ /**
+ * set state.
+ *
+ * @param state state
+ */
+ public void setState(final Integer state) {
+ this.state = state;
+ }
+
+ /**
+ * get tagId.
+ *
+ * @return tagId
+ */
+ public String getTagId() {
+ return tagId;
+ }
+
+ /**
+ * set tagId.
+ *
+ * @param tagId tagId
+ */
+ public void setTagId(final String tagId) {
+ this.tagId = tagId;
+ }
+
+ /**
+ * get pageParameter.
+ *
+ * @return pageParameter
+ */
+ public PageParameter getPageParameter() {
+ return pageParameter;
+ }
+
+ /**
+ * set pageParameter.
+ *
+ * @param pageParameter pageParameter
+ */
+ public void setPageParameter(final PageParameter pageParameter) {
+ this.pageParameter = pageParameter;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ApiQuery)) {
+ return false;
+ }
+ ApiQuery apiQuery = (ApiQuery) o;
+ return apiPath.equals(apiQuery.apiPath) &&
state.equals(apiQuery.state) && tagId.equals(apiQuery.tagId) &&
pageParameter.equals(apiQuery.pageParameter);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(apiPath, state, tagId, pageParameter);
+ }
+}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/TagRelationQuery.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/TagRelationQuery.java
index 6a69244f3..505027dd3 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/TagRelationQuery.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/query/TagRelationQuery.java
@@ -83,4 +83,59 @@ public class TagRelationQuery {
public int hashCode() {
return Objects.hash(apiId, tagId);
}
+
+ /**
+ * builder.
+ * @return TagRelationQueryBuilder
+ */
+ public static TagRelationQueryBuilder builder() {
+ return new TagRelationQueryBuilder();
+ }
+
+ public static final class TagRelationQueryBuilder {
+
+ /**
+ * apiId.
+ */
+ private String apiId;
+
+ /**
+ * tagId.
+ */
+ private String tagId;
+
+ private TagRelationQueryBuilder() {
+ }
+
+ /**
+ * build apiId.
+ * @param apiId apiId
+ * @return TagRelationQueryBuilder
+ */
+ public TagRelationQueryBuilder apiId(final String apiId) {
+ this.apiId = apiId;
+ return this;
+ }
+
+ /**
+ * build tagId.
+ * @param tagId tagId
+ * @return TagRelationQueryBuilder
+ */
+ public TagRelationQueryBuilder tagId(final String tagId) {
+ this.tagId = tagId;
+ return this;
+ }
+
+ /**
+ * build.
+ * @return TagRelationQuery
+ */
+ public TagRelationQuery build() {
+ TagRelationQuery tagRelationQuery = new TagRelationQuery();
+ tagRelationQuery.setApiId(apiId);
+ tagRelationQuery.setTagId(tagId);
+ return tagRelationQuery;
+ }
+ }
}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/ApiVO.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/ApiVO.java
new file mode 100644
index 000000000..941515aa8
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/vo/ApiVO.java
@@ -0,0 +1,790 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.model.vo;
+
+import org.apache.shenyu.admin.model.entity.ApiDO;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * this is api view to web front.
+ */
+public class ApiVO implements Serializable {
+
+ private static final long serialVersionUID = 7944745026885343719L;
+
+ /**
+ * primary key id.
+ */
+ private String id;
+
+ /**
+ * the context_path.
+ */
+ private String contextPath;
+
+ /**
+ * the apiPath.
+ */
+ private String apiPath;
+
+ /**
+ * 0-get,1-head,2-post,3-put,4-patch,5-delete,6-options,7-trace.
+ */
+ private Integer httpMethod;
+
+ /**
+ * specify the submitted content type for processing requests, such as
application/json, text/html;.
+ */
+ private String consume;
+
+ /**
+ * specify the content type to be returned. only when the (accept) type in
the request header contains the specified type can it be returned;.
+ */
+ private String produce;
+
+ /**
+ * api version,for example V0.01.
+ */
+ private String version;
+
+ /**
+ * http,dubbo,sofa,tars,websocket,springCloud,motan,grpc.
+ */
+ private String rpcType;
+
+ /**
+ * 0-unpublished1-published2-offline.
+ */
+ private Integer state;
+
+ /**
+ * extended fields.
+ */
+ private String ext;
+
+ /**
+ * apiOwner.
+ */
+ private String apiOwner;
+
+ /**
+ * the api description.
+ */
+ private String apiDesc;
+
+ /**
+ * 0-swagger,1-annotation generation,2-create manuallym,3-import
swagger,4-import yapi.
+ */
+ private Integer apiSource;
+
+ /**
+ * complete documentation of the api, including request parameters and
response parameters.
+ */
+ private String document;
+
+ /**
+ * document_md5.
+ */
+ private String documentMd5;
+
+ /**
+ * create time.
+ */
+ private Date dateCreated;
+
+ /**
+ * update time.
+ */
+ private Date dateUpdated;
+
+ /**
+ * tags.
+ */
+ private List<TagVO> tags;
+
+ /**
+ * getId.
+ *
+ * @return id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * set id.
+ *
+ * @param id id
+ */
+ public void setId(final String id) {
+ this.id = id;
+ }
+
+ /**
+ * getContextPath.
+ *
+ * @return context path
+ */
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ /**
+ * set context path.
+ *
+ * @param contextPath context path
+ */
+ public void setContextPath(final String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ /**
+ * getApiPath.
+ *
+ * @return apiPath
+ */
+ public String getApiPath() {
+ return apiPath;
+ }
+
+ /**
+ * setApiPath.
+ *
+ * @param apiPath apiPath
+ */
+ public void setApiPath(final String apiPath) {
+ this.apiPath = apiPath;
+ }
+
+ /**
+ * getHttpMethod.
+ *
+ * @return http method
+ */
+ public Integer getHttpMethod() {
+ return httpMethod;
+ }
+
+ /**
+ * setHttpMethod.
+ *
+ * @param httpMethod http method
+ */
+ public void setHttpMethod(final Integer httpMethod) {
+ this.httpMethod = httpMethod;
+ }
+
+ /**
+ * getConsume.
+ *
+ * @return consume
+ */
+ public String getConsume() {
+ return consume;
+ }
+
+ /**
+ * setConsume.
+ *
+ * @param consume consume
+ */
+ public void setConsume(final String consume) {
+ this.consume = consume;
+ }
+
+ /**
+ * getProduce.
+ *
+ * @return produce
+ */
+ public String getProduce() {
+ return produce;
+ }
+
+ /**
+ * setProduce.
+ *
+ * @param produce the produce
+ */
+ public void setProduce(final String produce) {
+ this.produce = produce;
+ }
+
+ /**
+ * getVersion.
+ *
+ * @return version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * setVersion.
+ *
+ * @param version the version
+ */
+ public void setVersion(final String version) {
+ this.version = version;
+ }
+
+ /**
+ * getRpcType.
+ *
+ * @return rpc type
+ */
+ public String getRpcType() {
+ return rpcType;
+ }
+
+ /**
+ * setRpcType.
+ *
+ * @param rpcType the rpc type
+ */
+ public void setRpcType(final String rpcType) {
+ this.rpcType = rpcType;
+ }
+
+ /**
+ * getState.
+ *
+ * @return state
+ */
+ public Integer getState() {
+ return state;
+ }
+
+ /**
+ * setState.
+ *
+ * @param state state
+ */
+ public void setState(final Integer state) {
+ this.state = state;
+ }
+
+ /**
+ * getExt.
+ *
+ * @return extension.
+ */
+ public String getExt() {
+ return ext;
+ }
+
+ /**
+ * setExt.
+ *
+ * @param ext extension
+ */
+ public void setExt(final String ext) {
+ this.ext = ext;
+ }
+
+ /**
+ * getApiOwner.
+ *
+ * @return apiOwner
+ */
+ public String getApiOwner() {
+ return apiOwner;
+ }
+
+ /**
+ * setApiOwner.
+ *
+ * @param apiOwner apiOwner
+ */
+ public void setApiOwner(final String apiOwner) {
+ this.apiOwner = apiOwner;
+ }
+
+ /**
+ * getApiDesc.
+ *
+ * @return apiDesc
+ */
+ public String getApiDesc() {
+ return apiDesc;
+ }
+
+ /**
+ * setApiDesc.
+ *
+ * @param apiDesc apiDesc
+ */
+ public void setApiDesc(final String apiDesc) {
+ this.apiDesc = apiDesc;
+ }
+
+ /**
+ * getApiSource.
+ *
+ * @return apiSource
+ */
+ public Integer getApiSource() {
+ return apiSource;
+ }
+
+ /**
+ * setSource.
+ *
+ * @param apiSource apiSource
+ */
+ public void setApiSource(final Integer apiSource) {
+ this.apiSource = apiSource;
+ }
+
+ /**
+ * getDocument.
+ *
+ * @return document
+ */
+ public String getDocument() {
+ return document;
+ }
+
+ /**
+ * setDocument.
+ *
+ * @param document document
+ */
+ public void setDocument(final String document) {
+ this.document = document;
+ }
+
+ /**
+ * getDocumentMd5.
+ *
+ * @return document md5
+ */
+ public String getDocumentMd5() {
+ return documentMd5;
+ }
+
+ /**
+ * setDocumentMd5.
+ *
+ * @param documentMd5 documentMd5
+ */
+ public void setDocumentMd5(final String documentMd5) {
+ this.documentMd5 = documentMd5;
+ }
+
+ /**
+ * getDateCreated.
+ *
+ * @return dateCreated
+ */
+ public Date getDateCreated() {
+ return dateCreated;
+ }
+
+ /**
+ * setDateCreated.
+ *
+ * @param dateCreated dateCreated
+ */
+ public void setDateCreated(final Date dateCreated) {
+ this.dateCreated = dateCreated;
+ }
+
+ /**
+ * getDateUpdated.
+ *
+ * @return dateUpdated
+ */
+ public Date getDateUpdated() {
+ return dateUpdated;
+ }
+
+ /**
+ * setDateUpdated.
+ *
+ * @param dateUpdated dateUpdated
+ */
+ public void setDateUpdated(final Date dateUpdated) {
+ this.dateUpdated = dateUpdated;
+ }
+
+
+ /**
+ * getTags.
+ *
+ * @return tags
+ */
+ public List<TagVO> getTags() {
+ return tags;
+ }
+
+ /**
+ * setTags.
+ *
+ * @param tags tags
+ */
+ public void setTags(final List<TagVO> tags) {
+ this.tags = tags;
+ }
+
+ /**
+ * builder.
+ *
+ * @return ApiVOBuilder
+ */
+ public static ApiVOBuilder builder() {
+ return new ApiVOBuilder();
+ }
+
+ /**
+ * buildApiVO.
+ *
+ * @param apiDO apiDO.
+ * @param tags tags.
+ * @return ApiVO.
+ */
+ public static ApiVO buildApiVO(final ApiDO apiDO, final List<TagVO> tags) {
+ return ApiVO.builder()
+ .id(apiDO.getId())
+ .contextPath(apiDO.getContextPath())
+ .apiPath(apiDO.getApiPath())
+ .httpMethod(apiDO.getHttpMethod())
+ .consume(apiDO.getConsume())
+ .produce(apiDO.getProduce())
+ .version(apiDO.getVersion())
+ .rpcType(apiDO.getRpcType())
+ .state(apiDO.getState())
+ .ext(apiDO.getExt())
+ .apiOwner(apiDO.getApiOwner())
+ .apiDesc(apiDO.getApiDesc())
+ .apiSource(apiDO.getApiSource())
+ .document(apiDO.getDocument())
+ .documentMd5(apiDO.getDocumentMd5())
+ .dateCreated(apiDO.getDateCreated())
+ .dateUpdated(apiDO.getDateUpdated())
+ .tags(tags)
+ .build();
+ }
+
+ public static final class ApiVOBuilder {
+
+ /**
+ * id.
+ */
+ private String id;
+
+ /**
+ * contextPath.
+ */
+ private String contextPath;
+
+ /**
+ * apiPath.
+ */
+ private String apiPath;
+
+ /**
+ * httpMethod.
+ */
+ private Integer httpMethod;
+
+ /**
+ * consume.
+ */
+ private String consume;
+
+ /**
+ * produce.
+ */
+ private String produce;
+
+ /**
+ * version.
+ */
+ private String version;
+
+ /**
+ * rpcType.
+ */
+ private String rpcType;
+
+ /**
+ * status.
+ */
+ private Integer state;
+
+ /**
+ * ext.
+ */
+ private String ext;
+
+ /**
+ * apiOwner.
+ */
+ private String apiOwner;
+
+ /**
+ * apiDesc.
+ */
+ private String apiDesc;
+
+ /**
+ * apiSource.
+ */
+ private Integer apiSource;
+
+ /**
+ * document.
+ */
+ private String document;
+
+ /**
+ * documentMd5.
+ */
+ private String documentMd5;
+
+ /**
+ * dateCreated.
+ */
+ private Date dateCreated;
+
+ /**
+ * dateUpdated.
+ */
+ private Date dateUpdated;
+
+ /**
+ * tags.
+ */
+ private List<TagVO> tags;
+
+ private ApiVOBuilder() {
+
+ }
+
+ /**
+ * builder id.
+ * @param id id
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder id(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * builder contextPath.
+ * @param contextPath contextPath
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder contextPath(final String contextPath) {
+ this.contextPath = contextPath;
+ return this;
+ }
+
+ /**
+ * build apiPath.
+ * @param apiPath apiPath
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder apiPath(final String apiPath) {
+ this.apiPath = apiPath;
+ return this;
+ }
+
+ /**
+ * build httpMethod.
+ * @param httpMethod httpMethod
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder httpMethod(final Integer httpMethod) {
+ this.httpMethod = httpMethod;
+ return this;
+ }
+
+ /**
+ * build consume.
+ * @param consume consume
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder consume(final String consume) {
+ this.consume = consume;
+ return this;
+ }
+
+ /**
+ * build produce.
+ * @param produce produce
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder produce(final String produce) {
+ this.produce = produce;
+ return this;
+ }
+
+ /**
+ * build version.
+ * @param version version
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder version(final String version) {
+ this.version = version;
+ return this;
+ }
+
+ /**
+ * build rpcType.
+ * @param rpcType rpcType
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder rpcType(final String rpcType) {
+ this.rpcType = rpcType;
+ return this;
+ }
+
+ /**
+ * build state.
+ * @param state state
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder state(final Integer state) {
+ this.state = state;
+ return this;
+ }
+
+ /**
+ * build ext.
+ * @param ext ext
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder ext(final String ext) {
+ this.ext = ext;
+ return this;
+ }
+
+ /**
+ * build apiOwner.
+ * @param apiOwner apiOwner
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder apiOwner(final String apiOwner) {
+ this.apiOwner = apiOwner;
+ return this;
+ }
+
+ /**
+ * build apiDesc.
+ * @param apiDesc apiDesc
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder apiDesc(final String apiDesc) {
+ this.apiDesc = apiDesc;
+ return this;
+ }
+
+ /**
+ * build apiSource.
+ * @param apiSource apiSource
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder apiSource(final Integer apiSource) {
+ this.apiSource = apiSource;
+ return this;
+ }
+
+ /**
+ * build document.
+ * @param document document
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder document(final String document) {
+ this.document = document;
+ return this;
+ }
+
+ /**
+ * build documentMd5.
+ * @param documentMd5 documentMd5
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder documentMd5(final String documentMd5) {
+ this.documentMd5 = documentMd5;
+ return this;
+ }
+
+ /**
+ * build dateCreated.
+ * @param dateCreated dateCreated
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder dateCreated(final Date dateCreated) {
+ this.dateCreated = dateCreated;
+ return this;
+ }
+
+ /**
+ * build dateUpdated.
+ * @param dateUpdated dateUpdated
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder dateUpdated(final Date dateUpdated) {
+ this.dateUpdated = dateUpdated;
+ return this;
+ }
+
+ /**
+ * build tags.
+ * @param tags tags
+ * @return ApiVOBuilder
+ */
+ public ApiVOBuilder tags(final List<TagVO> tags) {
+ this.tags = tags;
+ return this;
+ }
+
+ /**
+ * build.
+ * @return ApiVO
+ */
+ public ApiVO build() {
+ ApiVO apiVO = new ApiVO();
+ apiVO.setId(id);
+ apiVO.setContextPath(contextPath);
+ apiVO.setApiPath(apiPath);
+ apiVO.setHttpMethod(httpMethod);
+ apiVO.setConsume(consume);
+ apiVO.setProduce(produce);
+ apiVO.setVersion(version);
+ apiVO.setRpcType(rpcType);
+ apiVO.setState(state);
+ apiVO.setExt(ext);
+ apiVO.setApiOwner(apiOwner);
+ apiVO.setApiDesc(apiDesc);
+ apiVO.setApiSource(apiSource);
+ apiVO.setDocument(document);
+ apiVO.setDocumentMd5(documentMd5);
+ apiVO.setDateCreated(dateCreated);
+ apiVO.setDateUpdated(dateUpdated);
+ apiVO.setTags(tags);
+ return apiVO;
+ }
+ }
+}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/ApiService.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/ApiService.java
new file mode 100644
index 000000000..1440eb5a2
--- /dev/null
+++ b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/ApiService.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.service;
+
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.admin.model.page.CommonPager;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.model.vo.PluginVO;
+
+import java.util.List;
+
+/**
+ * this is api service.
+ */
+public interface ApiService {
+
+ /**
+ * Create or update string.
+ *
+ * @param apiDTO the api dto
+ * @return the string
+ */
+ String createOrUpdate(ApiDTO apiDTO);
+
+ /**
+ * Delete string.
+ *
+ * @param ids the ids
+ * @return the string
+ */
+ String delete(List<String> ids);
+
+ /**
+ * find api by id.
+ *
+ * @param id pk.
+ * @return {@linkplain PluginVO}
+ */
+ ApiVO findById(String id);
+
+
+ /**
+ * find page of api by query.
+ *
+ * @param apiQuery {@linkplain ApiQuery}
+ * @return {@linkplain CommonPager}
+ */
+ CommonPager<ApiVO> listByPage(ApiQuery apiQuery);
+}
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
new file mode 100644
index 000000000..3aa1cd07f
--- /dev/null
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ApiServiceImpl.java
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.service.impl;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.mapper.ApiMapper;
+import org.apache.shenyu.admin.mapper.TagMapper;
+import org.apache.shenyu.admin.mapper.TagRelationMapper;
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.admin.model.entity.ApiDO;
+import org.apache.shenyu.admin.model.entity.TagDO;
+import org.apache.shenyu.admin.model.entity.TagRelationDO;
+import org.apache.shenyu.admin.model.page.CommonPager;
+import org.apache.shenyu.admin.model.page.PageResultUtils;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.model.query.TagRelationQuery;
+import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.model.vo.TagVO;
+import org.apache.shenyu.admin.service.ApiService;
+import org.apache.shenyu.admin.utils.ListUtil;
+import org.apache.shenyu.admin.utils.ShenyuResultMessage;
+import org.apache.shenyu.common.constant.AdminConstants;
+import org.apache.shenyu.common.utils.UUIDUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * Implementation of the {@link org.apache.shenyu.admin.service.ApiService}.
+ */
+@Service
+public class ApiServiceImpl implements ApiService {
+
+ private final ApiMapper apiMapper;
+
+ private final TagRelationMapper tagRelationMapper;
+
+ private final TagMapper tagMapper;
+
+ public ApiServiceImpl(final ApiMapper apiMapper, final TagRelationMapper
tagRelationMapper,
+ final TagMapper tagMapper) {
+ this.apiMapper = apiMapper;
+ this.tagRelationMapper = tagRelationMapper;
+ this.tagMapper = tagMapper;
+
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public String createOrUpdate(final ApiDTO apiDTO) {
+ return StringUtils.isBlank(apiDTO.getId()) ? this.create(apiDTO) :
this.update(apiDTO);
+ }
+
+ /**
+ * update.
+ *
+ * @param apiDTO apiDTO
+ * @return update message
+ */
+ private String update(final ApiDTO apiDTO) {
+ ApiDO apiDO = ApiDO.buildApiDO(apiDTO);
+ final int updateRows = apiMapper.updateByPrimaryKeySelective(apiDO);
+ if (CollectionUtils.isNotEmpty(apiDTO.getTagIds()) && updateRows > 0) {
+ List<String> tagIds = apiDTO.getTagIds();
+ List<TagRelationDO> tags = Lists.newArrayList();
+ Timestamp currentTime = new Timestamp(System.currentTimeMillis());
+ for (String tagId : tagIds) {
+ tags.add(TagRelationDO.builder()
+ .id(UUIDUtils.getInstance().generateShortUuid())
+ .apiId(apiDO.getId())
+ .tagId(tagId)
+ .dateCreated(currentTime)
+ .dateUpdated(currentTime)
+ .build());
+ }
+ tagRelationMapper.deleteByApiId(apiDO.getId());
+ tagRelationMapper.batchInsert(tags);
+ }
+ return ShenyuResultMessage.UPDATE_SUCCESS;
+ }
+
+ /**
+ * create.
+ *
+ * @param apiDTO apiDTO
+ * @return create message
+ */
+ private String create(final ApiDTO apiDTO) {
+ ApiDO apiDO = ApiDO.buildApiDO(apiDTO);
+ final int insertRows = apiMapper.insertSelective(apiDO);
+ if (CollectionUtils.isNotEmpty(apiDTO.getTagIds()) && insertRows > 0) {
+ List<String> tagIds = apiDTO.getTagIds();
+ List<TagRelationDO> tags = Lists.newArrayList();
+ Timestamp currentTime = new Timestamp(System.currentTimeMillis());
+ for (String tagId : tagIds) {
+ tags.add(TagRelationDO.builder()
+ .id(UUIDUtils.getInstance().generateShortUuid())
+ .apiId(apiDO.getId())
+ .tagId(tagId)
+ .dateCreated(currentTime)
+ .dateUpdated(currentTime)
+ .build());
+ }
+ tagRelationMapper.batchInsert(tags);
+ }
+ return ShenyuResultMessage.CREATE_SUCCESS;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public String delete(final List<String> ids) {
+ // select api id.
+ List<ApiDO> apis = this.apiMapper.selectByIds(ids);
+ if (CollectionUtils.isEmpty(apis)) {
+ return AdminConstants.SYS_API_ID_NOT_EXIST;
+ }
+ // delete apis.
+ final List<String> apiIds = ListUtil.map(apis, ApiDO::getId);
+ final int deleteRows = this.apiMapper.deleteByIds(apiIds);
+ if (deleteRows > 0) {
+ tagRelationMapper.deleteByApiIds(apiIds);
+ }
+ return StringUtils.EMPTY;
+ }
+
+ @Override
+ public ApiVO findById(final String id) {
+ return Optional.ofNullable(apiMapper.selectByPrimaryKey(id)).map(item
-> {
+ List<TagRelationDO> tagRelations =
tagRelationMapper.selectByQuery(TagRelationQuery.builder().apiId(item.getId()).build());
+ List<String> tagIds =
tagRelations.stream().map(TagRelationDO::getTagId).collect(Collectors.toList());
+ List<TagVO> tagVOS = Lists.newArrayList();
+ if (CollectionUtils.isNotEmpty(tagIds)) {
+ List<TagDO> tagDOS = tagMapper.selectByIds(tagIds);
+ for (TagDO tagDO : tagDOS) {
+ tagVOS.add(TagVO.buildTagVO(tagDO));
+ }
+ }
+ return ApiVO.buildApiVO(item, tagVOS);
+ }).orElse(null);
+ }
+
+ @Override
+ public CommonPager<ApiVO> listByPage(final ApiQuery apiQuery) {
+ return PageResultUtils.result(apiQuery.getPageParameter(), () ->
apiMapper.selectByQuery(apiQuery)
+ .stream().map(item -> {
+ List<TagRelationDO> tagRelations =
tagRelationMapper.selectByQuery(TagRelationQuery.builder().apiId(item.getId()).build());
+ List<String> tagIds =
tagRelations.stream().map(TagRelationDO::getTagId).collect(Collectors.toList());
+ List<TagVO> tagVOS = Lists.newArrayList();
+ if (CollectionUtils.isNotEmpty(tagIds)) {
+ List<TagDO> tagDOS = tagMapper.selectByIds(tagIds);
+ for (TagDO tagDO : tagDOS) {
+ tagVOS.add(TagVO.buildTagVO(tagDO));
+ }
+ }
+ return ApiVO.buildApiVO(item, tagVOS);
+ }).collect(Collectors.toList()));
+ }
+}
diff --git a/shenyu-admin/src/main/resources/mappers/api-sqlmap.xml
b/shenyu-admin/src/main/resources/mappers/api-sqlmap.xml
index 43504947d..9468d0630 100644
--- a/shenyu-admin/src/main/resources/mappers/api-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/api-sqlmap.xml
@@ -39,6 +39,7 @@
<result column="date_created" jdbcType="TIMESTAMP" property="dateCreated"
/>
<result column="date_updated" jdbcType="TIMESTAMP" property="dateUpdated"
/>
</resultMap>
+
<sql id="Base_Column_List">
<[email protected]>
id, context_path, api_path, http_method, consume, produce, version,
rpc_type, `state`,
@@ -257,4 +258,64 @@
date_updated = #{dateUpdated,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=VARCHAR}
</update>
+
+ <select id="existed" resultType="java.lang.Boolean">
+ select true
+ from api
+ where id = #{id} limit 1
+ </select>
+
+ <select id="selectByQuery"
parameterType="org.apache.shenyu.admin.model.query.ApiQuery"
+ resultMap="BaseResultMap">
+ select api.id,
+ api.context_path,
+ api.api_path,
+ api.http_method,
+ api.consume,
+ api.produce,
+ api.version,
+ api.rpc_type,
+ api.`state`,
+ api.ext,
+ api.api_owner,
+ api.api_desc,
+ api.api_source,
+ api.document,
+ api.document_md5,
+ api.date_created,
+ api.date_updated
+ from api
+ <if test="tagId != null and tagId != ''">
+ inner join tag_relation on api.id = tag_relation.api_id and
tag_relation.tag_id = #{tagId,jdbcType=VARCHAR}
+ </if>
+ <where>
+ <if test="apiPath != null and apiPath != ''">
+ <bind name="nameLike" value="('%' + apiPath + '%')"/>
+ and api_path LIKE #{nameLike, jdbcType=VARCHAR}
+ </if>
+ <if test="state != null">
+ and state = #{state, jdbcType=TINYINT}
+ </if>
+ </where>
+ order by api.date_created desc
+ </select>
+
+ <select id="selectByIds" parameterType="java.util.List"
resultMap="BaseResultMap">
+ SELECT
+ <include refid="Base_Column_List"/>
+ FROM api
+ WHERE id IN
+ <foreach item="id" collection="list" open="(" separator="," close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ </select>
+
+ <delete id="deleteByIds" parameterType="java.util.List">
+ DELETE FROM api
+ WHERE id IN
+ <foreach item="id" collection="list" open="(" separator="," close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ </delete>
+
</mapper>
\ No newline at end of file
diff --git a/shenyu-admin/src/main/resources/mappers/tag-relation-sqlmap.xml
b/shenyu-admin/src/main/resources/mappers/tag-relation-sqlmap.xml
index 92b2cd906..6fd464c06 100644
--- a/shenyu-admin/src/main/resources/mappers/tag-relation-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/tag-relation-sqlmap.xml
@@ -147,4 +147,35 @@
#{id, jdbcType=VARCHAR}
</foreach>
</delete>
+
+ <insert id="batchInsert" parameterType="java.util.List">
+ INSERT INTO tag_relation
+ (id,
+ date_created,
+ date_updated,
+ api_id,
+ tag_id)
+ VALUES
+ <foreach collection="list" item="item" separator=",">
+ (#{item.id, jdbcType=VARCHAR},
+ #{item.dateCreated, jdbcType=TIMESTAMP},
+ #{item.dateUpdated, jdbcType=TIMESTAMP},
+ #{item.apiId, jdbcType=VARCHAR},
+ #{item.tagId, jdbcType=VARCHAR})
+ </foreach>
+ </insert>
+
+ <delete id="deleteByApiId">
+ delete
+ from tag_relation
+ where api_id = #{apiId,jdbcType=VARCHAR}
+ </delete>
+
+ <delete id="deleteByApiIds" parameterType="java.util.List">
+ DELETE FROM tag_relation
+ WHERE api_id IN
+ <foreach item="id" collection="apiIds" open="(" separator=","
close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ </delete>
</mapper>
diff --git a/shenyu-admin/src/main/resources/mappers/tag-sqlmap.xml
b/shenyu-admin/src/main/resources/mappers/tag-sqlmap.xml
index 21974c641..f303e4ab2 100644
--- a/shenyu-admin/src/main/resources/mappers/tag-sqlmap.xml
+++ b/shenyu-admin/src/main/resources/mappers/tag-sqlmap.xml
@@ -62,7 +62,7 @@
<select id="selectByParentTagIds" parameterType="java.util.List"
resultMap="BaseResultMap">
SELECT
- <include refid="Base_Column_List"/>
+ <include refid="Base_Column_List"/>
FROM tag
WHERE parent_tag_id IN
<foreach item="id" collection="list" open="(" separator="," close=")">
@@ -189,4 +189,14 @@
<delete id="deleteAllData" >
delete from tag
</delete>
+
+ <select id="selectByIds" resultMap="BaseResultMap">
+ SELECT
+ <include refid="Base_Column_List"/>
+ FROM tag
+ WHERE id IN
+ <foreach item="id" collection="list" open="(" separator="," close=")">
+ #{id, jdbcType=VARCHAR}
+ </foreach>
+ </select>
</mapper>
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ApiControllerTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ApiControllerTest.java
new file mode 100644
index 000000000..a6d24cf63
--- /dev/null
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ApiControllerTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.controller;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shenyu.admin.exception.ExceptionHandlers;
+import org.apache.shenyu.admin.mapper.ApiMapper;
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.admin.model.page.CommonPager;
+import org.apache.shenyu.admin.model.page.PageParameter;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.service.ApiService;
+import org.apache.shenyu.admin.spring.SpringBeanUtils;
+import org.apache.shenyu.admin.utils.ShenyuResultMessage;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.core.Is.is;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static
org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static
org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+/**
+ * Test cases for ApiController.
+ */
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public final class ApiControllerTest {
+
+ private MockMvc mockMvc;
+
+ @InjectMocks
+ private ApiController apiController;
+
+ @Mock
+ private ApiService apiService;
+
+ @Mock
+ private ApiMapper apiMapper;
+
+ private ApiVO apiVO;
+
+ @BeforeEach
+ public void setUp() {
+ this.mockMvc = MockMvcBuilders.standaloneSetup(apiController)
+ .setControllerAdvice(new ExceptionHandlers())
+ .build();
+ this.apiVO = ApiVO.builder()
+ .id("123")
+ .contextPath("string")
+ .apiPath("string")
+ .httpMethod(0)
+ .consume("string")
+ .produce("string")
+ .version("string")
+ .rpcType("/dubbo")
+ .state(0)
+ .apiSource(0)
+ .document("document")
+ .build();
+
SpringBeanUtils.getInstance().setApplicationContext(mock(ConfigurableApplicationContext.class));
+ }
+
+ @Test
+ public void testQueryApis() throws Exception {
+ final PageParameter pageParameter = new PageParameter();
+ List<ApiVO> apiVOS = new ArrayList<>();
+ apiVOS.add(apiVO);
+ final CommonPager<ApiVO> commonPager = new CommonPager<>();
+ commonPager.setPage(pageParameter);
+ commonPager.setDataList(apiVOS);
+ final ApiQuery apiQuery = new ApiQuery("string", 0, "", pageParameter);
+ given(this.apiService.listByPage(apiQuery)).willReturn(commonPager);
+ this.mockMvc.perform(MockMvcRequestBuilders.get("/api")
+ .param("apiPath", "string")
+ .param("state", "0")
+ .param("tagId", "")
+ .param("currentPage", pageParameter.getCurrentPage() + "")
+ .param("pageSize", pageParameter.getPageSize() + ""))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message",
is(ShenyuResultMessage.QUERY_SUCCESS)))
+ .andExpect(jsonPath("$.data.dataList[0].contextPath",
is(apiVO.getContextPath())))
+ .andReturn();
+ }
+
+ @Test
+ public void testDetailApi() throws Exception {
+ given(this.apiService.findById("123")).willReturn(apiVO);
+ this.mockMvc.perform(MockMvcRequestBuilders.get("/api/{id}", "123"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message",
is(ShenyuResultMessage.DETAIL_SUCCESS)))
+ .andExpect(jsonPath("$.data.id", is(apiVO.getId())))
+ .andReturn();
+ }
+
+ @Test
+ public void testCreateApi() throws Exception {
+ ApiDTO apiDTO = new ApiDTO();
+ apiDTO.setContextPath("string");
+ apiDTO.setApiPath("string");
+ apiDTO.setHttpMethod(0);
+ apiDTO.setConsume("string");
+ apiDTO.setProduce("string");
+ apiDTO.setVersion("string");
+ apiDTO.setRpcType("/dubbo");
+ apiDTO.setState(0);
+ apiDTO.setApiOwner("string");
+ apiDTO.setApiDesc("string");
+ apiDTO.setApiSource(0);
+ apiDTO.setDocument("document");
+ apiDTO.setExt("ext");
+
given(this.apiService.createOrUpdate(apiDTO)).willReturn(ShenyuResultMessage.CREATE_SUCCESS);
+ this.mockMvc.perform(MockMvcRequestBuilders.post("/api")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(GsonUtils.getInstance().toJson(apiDTO)))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message",
is(ShenyuResultMessage.CREATE_SUCCESS)))
+ .andReturn();
+ }
+
+ @Test
+ public void testUpdateApi() throws Exception {
+ ApiDTO apiDTO = new ApiDTO();
+ apiDTO.setContextPath("string");
+ apiDTO.setApiPath("string");
+ apiDTO.setHttpMethod(0);
+ apiDTO.setConsume("string");
+ apiDTO.setProduce("string");
+ apiDTO.setVersion("string");
+ apiDTO.setRpcType("/dubbo");
+ apiDTO.setState(0);
+ apiDTO.setApiOwner("string");
+ apiDTO.setApiDesc("string");
+ apiDTO.setApiSource(0);
+ apiDTO.setDocument("document");
+ apiDTO.setExt("ext");
+ apiDTO.setId("123");
+
when(SpringBeanUtils.getInstance().getBean(ApiMapper.class)).thenReturn(apiMapper);
+ when(apiMapper.existed(apiDTO.getId())).thenReturn(true);
+
given(this.apiService.createOrUpdate(apiDTO)).willReturn(ShenyuResultMessage.UPDATE_SUCCESS);
+ this.mockMvc.perform(MockMvcRequestBuilders.put("/api/{id}",
apiDTO.getId())
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(GsonUtils.getInstance().toJson(apiDTO)))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message",
is(ShenyuResultMessage.UPDATE_SUCCESS)))
+ .andReturn();
+
+ }
+
+ @Test
+ public void testDeleteApis() throws Exception {
+
given(this.apiService.delete(Collections.singletonList("123"))).willReturn(StringUtils.EMPTY);
+ this.mockMvc.perform(MockMvcRequestBuilders.delete("/api/batch")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content("[\"123\"]"))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.message",
is(ShenyuResultMessage.DELETE_SUCCESS)))
+ .andReturn();
+
+ }
+
+}
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/ApiMapperTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/ApiMapperTest.java
index 5ec9292cc..ce75f8dc6 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/ApiMapperTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/mapper/ApiMapperTest.java
@@ -74,7 +74,7 @@ public final class ApiMapperTest extends
AbstractSpringIntegrationTest {
this.apiDO.setHttpMethod(1);
this.apiDO.setVersion("V0.02");
this.apiDO.setRpcType("dubbo1");
- this.apiDO.setState((byte) 1);
+ this.apiDO.setState(1);
final int count = apiMapper.updateByPrimaryKeySelective(this.apiDO);
assertEquals(1, count);
}
@@ -88,7 +88,7 @@ public final class ApiMapperTest extends
AbstractSpringIntegrationTest {
this.apiDO.setHttpMethod(2);
this.apiDO.setVersion("V0.03");
this.apiDO.setRpcType("dubbo2");
- this.apiDO.setState((byte) 2);
+ this.apiDO.setState(2);
this.apiDO.setApiSource(3);
final int count = apiMapper.updateByPrimaryKeySelective(this.apiDO);
assertEquals(1, count);
@@ -111,7 +111,7 @@ public final class ApiMapperTest extends
AbstractSpringIntegrationTest {
apiDO.setProduce("accept");
apiDO.setVersion("V0.01");
apiDO.setRpcType("dubbo");
- apiDO.setState((byte) 0);
+ apiDO.setState(0);
apiDO.setExt("ext");
apiDO.setApiOwner("admin");
apiDO.setApiDesc("hello world api");
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
new file mode 100644
index 000000000..2ea6b411d
--- /dev/null
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/ApiServiceTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+package org.apache.shenyu.admin.service;
+
+import org.apache.shenyu.admin.mapper.ApiMapper;
+import org.apache.shenyu.admin.mapper.TagMapper;
+import org.apache.shenyu.admin.mapper.TagRelationMapper;
+import org.apache.shenyu.admin.model.dto.ApiDTO;
+import org.apache.shenyu.admin.model.entity.ApiDO;
+import org.apache.shenyu.admin.model.page.CommonPager;
+import org.apache.shenyu.admin.model.page.PageParameter;
+import org.apache.shenyu.admin.model.query.ApiQuery;
+import org.apache.shenyu.admin.model.vo.ApiVO;
+import org.apache.shenyu.admin.service.impl.ApiServiceImpl;
+import org.apache.shenyu.admin.utils.ShenyuResultMessage;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.platform.commons.util.StringUtils;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test cases for ApiService.
+ */
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public final class ApiServiceTest {
+
+ @InjectMocks
+ private ApiServiceImpl apiService;
+
+ @Mock
+ private ApiMapper apiMapper;
+
+ @Mock
+ private TagRelationMapper tagRelationMapper;
+
+ @Mock
+ private TagMapper tagMapper;
+
+ @BeforeEach
+ public void setUp() {
+ apiService = new ApiServiceImpl(apiMapper, tagRelationMapper,
tagMapper);
+ }
+
+ @Test
+ public void testCreateOrUpdate() {
+ testCreate();
+ testUpdate("123");
+ }
+
+ @Test
+ public void testDelete() {
+ List<ApiDO> apis = Collections.singletonList(buildApiDO("123"));
+
when(apiMapper.selectByIds(Collections.singletonList("123"))).thenReturn(apis);
+
when(apiMapper.deleteByIds(Collections.singletonList("123"))).thenReturn(1);
+ assertEquals(org.apache.commons.lang3.StringUtils.EMPTY,
apiService.delete(Collections.singletonList("123")));
+ }
+
+ @Test
+ public void testFindById() {
+ String id = "123";
+ final ApiDO apiDO = buildApiDO(id);
+ given(this.apiMapper.selectByPrimaryKey(eq(id))).willReturn(apiDO);
+ ApiVO byId = this.apiService.findById(id);
+ assertNotNull(byId);
+ }
+
+ @Test
+ public void testListByPage() {
+ PageParameter pageParameter = new PageParameter();
+ pageParameter.setPageSize(5);
+ pageParameter.setTotalCount(10);
+ pageParameter.setTotalPage(pageParameter.getTotalCount() /
pageParameter.getPageSize());
+ ApiQuery apiQuery = new ApiQuery(null, 0, "", pageParameter);
+ List<ApiDO> apiDOList = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ final ApiDO apiDO = buildApiDO("" + i);
+ apiDOList.add(apiDO);
+ }
+ given(this.apiMapper.selectByQuery(apiQuery)).willReturn(apiDOList);
+ final CommonPager<ApiVO> apiDOCommonPager =
this.apiService.listByPage(apiQuery);
+ assertEquals(apiDOCommonPager.getDataList().size(), apiDOList.size());
+ }
+
+ private ApiDO buildApiDO(final String id) {
+ ApiDO apiDO = ApiDO.buildApiDO(buildApiDTO(id));
+ Timestamp now = Timestamp.valueOf(LocalDateTime.now());
+ apiDO.setDateCreated(now);
+ apiDO.setDateUpdated(now);
+ return apiDO;
+ }
+
+ private ApiVO buildApiVO(final String id) {
+ return ApiVO.builder()
+ .id(id)
+ .contextPath("string")
+ .apiPath("string")
+ .httpMethod(0)
+ .consume("string")
+ .produce("string")
+ .version("string")
+ .rpcType("string")
+ .state(0)
+ .apiOwner("string")
+ .apiDesc("string")
+ .apiSource(0)
+ .document("document")
+ .build();
+ }
+
+ private void testCreate() {
+ ApiDTO apiDTO = buildApiDTO("");
+ assertEquals(ShenyuResultMessage.CREATE_SUCCESS,
this.apiService.createOrUpdate(apiDTO));
+ }
+
+ private ApiDTO buildApiDTO(final String id) {
+ ApiDTO apiDTO = new ApiDTO();
+ if (StringUtils.isNotBlank(id)) {
+ apiDTO.setId(id);
+ }
+ apiDTO.setContextPath("string");
+ apiDTO.setApiPath("string");
+ apiDTO.setHttpMethod(0);
+ apiDTO.setConsume("string");
+ apiDTO.setProduce("string");
+ apiDTO.setVersion("string");
+ apiDTO.setRpcType("string");
+ apiDTO.setState(0);
+ apiDTO.setApiOwner("string");
+ apiDTO.setApiDesc("string");
+ apiDTO.setApiSource(0);
+ apiDTO.setDocument("document");
+ return apiDTO;
+ }
+
+ private void testUpdate(final String id) {
+ ApiDTO apiDTO = new ApiDTO();
+ apiDTO.setId(id);
+ apiDTO.setApiPath("test");
+ apiDTO.setDocument("testDocument");
+ assertEquals(ShenyuResultMessage.UPDATE_SUCCESS,
this.apiService.createOrUpdate(apiDTO));
+ }
+}
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
index 9457c89de..74ee4f5a6 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/AdminConstants.java
@@ -57,6 +57,11 @@ public final class AdminConstants {
*/
public static final String SYS_PLUGIN_ID_NOT_EXIST = "The plugin(s) does
not exist!";
+ /**
+ * The constant SYS_API_ID_NOT_EXIST.
+ */
+ public static final String SYS_API_ID_NOT_EXIST = "The api(s) does not
exist!";
+
/**
* The constant DATA_PATH_IS_EXIST.
*/