初步实现插件机制

This commit is contained in:
mxd
2022-01-22 22:40:39 +08:00
parent e6578fc3b3
commit 5710801fda
75 changed files with 985 additions and 469 deletions

View File

@@ -0,0 +1,49 @@
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestClient;
import java.io.IOException;
import java.util.Map;
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());
}
}

View File

@@ -0,0 +1,76 @@
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.utils.JsonUtils;
import org.ssssssss.script.annotation.Comment;
import java.io.IOException;
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));
}
}

View File

@@ -0,0 +1,30 @@
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.core.config.MagicModule;
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";
}
}

View File

@@ -0,0 +1,94 @@
package org.ssssssss.magicapi.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.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
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;
}
}

View File

@@ -0,0 +1,23 @@
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
@Configuration
public class MagicElasticSearchConfiguration implements MagicPluginConfiguration {
@Override
public Plugin plugin() {
return new Plugin("ElasticSearch");
}
@Bean
@ConditionalOnBean(RestHighLevelClient.class)
public ElasticSearchModule elasticSearchModule(RestHighLevelClient restHighLevelClient){
return new ElasticSearchModule(restHighLevelClient.getLowLevelClient());
}
}

View File

@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.elasticsearch.MagicElasticSearchConfiguration