提交 4c127532 编写于 作者: M mxd

删除`assert`模块,新增`ElasticSearch`模块

上级 b0bcb4ce
......@@ -28,6 +28,11 @@
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
......
......@@ -87,7 +87,7 @@ import java.util.function.BiFunction;
@Configuration
@ConditionalOnClass({RequestMappingHandlerMapping.class})
@EnableConfigurationProperties(MagicAPIProperties.class)
@Import({MagicRedisAutoConfiguration.class, MagicMongoAutoConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@Import({MagicRedisAutoConfiguration.class, MagicElasticSearchAutoConfiguration.class, MagicMongoAutoConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@EnableWebSocket
public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketConfigurer {
......@@ -500,8 +500,6 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
MagicResourceLoader.addModule("request", new RequestModule(multipartResolver));
logger.info("注册模块:{} -> {}", "response", ResponseModule.class);
MagicResourceLoader.addModule("response", new ResponseModule(resultProvider));
logger.info("注册模块:{} -> {}", "assert", AssertModule.class);
MagicResourceLoader.addModule("assert", new AssertModule());
magicModules.forEach(module -> {
logger.info("注册模块:{} -> {}", module.getModuleName(), module.getClass());
MagicResourceLoader.addModule(module.getModuleName(), module);
......
package org.ssssssss.magicapi.spring.boot.starter;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.ssssssss.magicapi.modules.ElasticSearchModule;
@Configuration
@ConditionalOnMissingBean(ElasticSearchModule.class)
@ConditionalOnClass(RestHighLevelClient.class)
public class MagicElasticSearchAutoConfiguration {
@Bean
@ConditionalOnBean(RestHighLevelClient.class)
public ElasticSearchModule elasticSearchModule(RestHighLevelClient restHighLevelClient){
return new ElasticSearchModule(restHighLevelClient.getLowLevelClient());
}
}
......@@ -41,6 +41,11 @@
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
......
......@@ -41,7 +41,7 @@ public interface JsonCodeConstants {
JsonCode FILE_PATH_NOT_EXISTS = new JsonCode(1015, "配置的文件路径不存在,请检查");
JsonCode REQUEST_PATH_CONFLICT = new JsonCode(1016, "接口[{}({})]与应用冲突,无法注册");
JsonCode REQUEST_PATH_CONFLICT = new JsonCode(1016, "接口[%s(%s)]与应用冲突,无法注册");
JsonCode SCRIPT_REQUIRED = new JsonCode(1017, "脚本内容不能为空");
......
package org.ssssssss.magicapi.modules;
import org.apache.commons.lang3.StringUtils;
import org.ssssssss.magicapi.config.MagicModule;
import org.ssssssss.script.annotation.Comment;
import org.ssssssss.script.exception.MagicScriptAssertException;
import java.util.regex.Pattern;
/**
* 断言模块
*
* @author mxd
*/
public class AssertModule implements MagicModule {
/**
* 判断值不能为null
*
* @param value 值
* @param code 状态码
* @param message 状态说明
*/
@Comment("判断值不能为空")
public void notNull(@Comment(name = "value", value = "值") Object value,
@Comment(name = "code", value = "判断失败时的code") int code,
@Comment(name = "message", value = "判断失败时的说明") String message) {
if (value == null) {
throw new MagicScriptAssertException(code, message);
}
}
/**
* 判断值不能为empty
*
* @param value 值
* @param code 状态码
* @param message 状态说明
*/
@Comment("判断值不能为Empty")
public void notEmpty(@Comment(name = "value", value = "值") String value,
@Comment(name = "code", value = "判断失败时的code") int code,
@Comment(name = "message", value = "判断失败时的说明") String message) {
if (StringUtils.isEmpty(value)) {
throw new MagicScriptAssertException(code, message);
}
}
/**
* 判断值不能为blank
*
* @param value 值
* @param code 状态码
* @param message 状态说明
*/
@Comment("判断值不能为Blank")
public void notBlank(@Comment(name = "value", value = "值") String value,
@Comment(name = "code", value = "判断失败时的code") int code,
@Comment(name = "message", value = "判断失败时的说明") String message) {
if (StringUtils.isBlank(value)) {
throw new MagicScriptAssertException(code, message);
}
}
/**
* 正则验证值
*
* @param value 值
* @param code 状态码
* @param message 状态说明
*/
@Comment("正则判断")
public void regx(@Comment(name = "value", value = "值") String value, String pattern,
@Comment(name = "code", value = "判断失败时的code") int code,
@Comment(name = "message", value = "判断失败时的说明") String message) {
if (value == null || !Pattern.compile(pattern).matcher(value).matches()) {
throw new MagicScriptAssertException(code, message);
}
}
/**
* 判断值值是否为true
*
* @param value 值
* @param code 状态码
* @param message 状态说明
*/
@Comment("判断值是否为true")
public void isTrue(@Comment(name = "value", value = "值") boolean value,
@Comment(name = "code", value = "判断失败时的code") int code,
@Comment(name = "message", value = "判断失败时的说明") String message) {
if (!value) {
throw new MagicScriptAssertException(code, message);
}
}
@Override
public String getModuleName() {
return "assert";
}
}
package org.ssssssss.magicapi.modules;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.config.MagicModule;
import org.ssssssss.magicapi.modules.elasticsearch.ElasticSearchConnection;
import org.ssssssss.magicapi.modules.elasticsearch.ElasticSearchIndex;
import org.ssssssss.script.annotation.Comment;
public class ElasticSearchModule implements MagicModule {
private static final String DOC = "_doc";
private final RestClient restClient;
public ElasticSearchModule(RestClient restClient) {
this.restClient = restClient;
}
@Comment(value = "ElasticSearch REST Api")
public ElasticSearchConnection rest(String url){
return new ElasticSearchConnection(this.restClient, url);
}
public ElasticSearchIndex index(String indexName){
return new ElasticSearchIndex(this.restClient, indexName, DOC);
}
@Override
public String getModuleName() {
return "elasticsearch";
}
}
package org.ssssssss.magicapi.modules.elasticsearch;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.ml.PutJobResponse;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
public class ElasticSearchConnection extends ElasticSearchRest {
public ElasticSearchConnection(RestClient restClient, String endpoint) {
super(restClient);
super.endpoint(endpoint);
}
public ElasticSearchConnection parameter(String key, String value) {
if (value != null) {
parameters.put(key, value);
}
return this;
}
public ElasticSearchConnection parameters(Map<String, String> params) {
if (params != null) {
parameters.putAll(params);
}
return this;
}
public Object put(Object data) throws IOException {
return processResponse(json(data).doPut());
}
public Object delete() throws IOException {
return processResponse(doDelete());
}
public Object delete(Object data) throws IOException {
return processResponse(json(data).doDelete());
}
public Object post(Object data) throws IOException {
return processResponse(json(data).doPost());
}
public Object get() throws IOException {
return processResponse(doGet());
}
}
package org.ssssssss.magicapi.modules.elasticsearch;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.utils.JsonUtils;
import org.ssssssss.script.annotation.Comment;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ElasticSearchIndex {
private final RestClient restClient;
private final String name;
private final String type;
public ElasticSearchIndex(RestClient restClient, String name, String type) {
this.restClient = restClient;
this.name = name;
this.type = type;
}
@Comment("根据`_id`保存,当存在时更新,不存在时插入")
public Object save(@Comment(value = "_id", name = "_id")String _id, @Comment(value = "保存对象", name = "data")Object data) throws IOException {
return connect("/%s/%s/%s", this.name, this.type, _id).post(data);
}
@Comment("不指定`_id`插入")
public Object insert(@Comment(value = "插入对象", name = "data")Object data) throws IOException {
return connect("/%s/%s", this.name, this.type).post(data);
}
@Comment("指定`_id`插入,当`_id`存在时不会更新")
public Object insert(@Comment(value = "_id", name = "_id")String _id, @Comment(value = "插入对象", name = "data")Object data) throws IOException {
return connect("/%s/%s/%s/_create", this.name, this.type, _id).post(data);
}
@Comment("根据`id`删除")
public Object delete(@Comment(value = "id", name = "id")String id) throws IOException {
return connect("/%s/%s/%s", this.name, this.type, id).delete();
}
@Comment("批量保存,当包含`id`时,则使用该列值匹配保存")
public Object bulkSave(@Comment(value = "保存内容", name = "list") List<Map<String, Object>> list) throws IOException {
StringBuilder builder = new StringBuilder();
list.forEach(item -> {
Object id = item.get("id");
if(id != null){
builder.append(String.format("{ \"index\":{ \"_id\": \"%s\" } }\r\n", id));
} else {
builder.append("{ \"index\":{} }\r\n");
}
builder.append(JsonUtils.toJsonStringWithoutPretty(item));
builder.append("\r\n");
});
return connect("/%s/%s/_bulk", this.name, this.type).post(builder.toString());
}
@Comment("根据`_id`修改")
public Object update(@Comment(value = "_id", name = "_id")String _id, @Comment(value = "修改项", name = "data")Object data) throws IOException {
return connect("/%s/%s/%s", this.name, this.type, _id).post(Collections.singletonMap("doc", data));
}
@Comment("搜索")
public Object search(@Comment(value = "搜索`DSL`语句", name = "dsl")Map<String, Object> dsl) throws IOException {
return connect("/%s/_search", this.name).post(dsl);
}
private ElasticSearchConnection connect(String format, Object... args) {
return new ElasticSearchConnection(this.restClient, String.format(format, args));
}
}
package org.ssssssss.magicapi.modules.elasticsearch;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.xcontent.XContentParserUtils;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class ElasticSearchRest {
private final RestClient restClient;
private String method;
private String endpoint = "/";
private HttpEntity entity;
protected final Map<String, String> parameters = new HashMap<>();
public ElasticSearchRest(RestClient restClient) {
this.restClient = restClient;
}
ElasticSearchRest endpoint(String endpoint){
this.endpoint = endpoint;
return this;
}
Response doGet() throws IOException {
this.method = "GET";
return execute();
}
Response doPost() throws IOException {
this.method = "POST";
return execute();
}
Response doDelete() throws IOException {
this.method = "DELETE";
return execute();
}
Response doPut() throws IOException {
this.method = "PUT";
return execute();
}
ElasticSearchRest json(Object data){
if(data == null){
return this;
}
String json = null;
if(data instanceof CharSequence){
json = data.toString();
} else {
json = JsonUtils.toJsonString(data);
}
if(json != null){
this.entity = new NStringEntity(json, ContentType.APPLICATION_JSON);
}
return this;
}
private Response execute() throws IOException {
Request request = new Request(method, this.endpoint);
request.addParameters(parameters);
request.setEntity(entity);
return this.restClient.performRequest(request);
}
Object processResponse(Response response) throws IOException {
int code = response.getStatusLine().getStatusCode();
if (code >= 200 && code < 300) { // 2xx
HttpEntity entity = response.getEntity();
String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8);
ContentType contentType = ContentType.get(entity);
if (Objects.equals(ContentType.APPLICATION_JSON.getMimeType(), contentType.getMimeType())) {
return JsonUtils.readValue(resp, Object.class);
}
}
return response;
}
}
......@@ -44,6 +44,15 @@ public class JsonUtils {
}
}
public static String toJsonStringWithoutPretty(Object target) {
try {
return MAPPER.writeValueAsString(target);
} catch (JsonProcessingException e) {
logger.error("json序列化失败", e);
return null;
}
}
public static String toJsonStringWithoutLog(Object target) {
try {
return MAPPER.writeValueAsString(target);
......
......@@ -30,7 +30,8 @@
</scm>
<properties>
<spring-boot.version>2.4.5</spring-boot.version>
<magic-script.version>1.6.3</magic-script.version>
<magic-script.version>1.6.4</magic-script.version>
<elasticsearch.version>7.15.0</elasticsearch.version>
<commons-compress.version>1.21</commons-compress.version>
<commons-io.version>2.7</commons-io.version>
<commons-text.version>1.6</commons-text.version>
......@@ -102,6 +103,11 @@
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册