feat(all): 搭建基本框架和模块
This commit is contained in:
46
gringotts-forest/pom.xml
Normal file
46
gringotts-forest/pom.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.eshore</groupId>
|
||||
<artifactId>gringotts</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>gringotts-forest</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.eshore</groupId>
|
||||
<artifactId>gringotts-configuration</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dtflys.forest</groupId>
|
||||
<artifactId>forest-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.eshore.gringotts.forest.configuration;
|
||||
|
||||
import com.dtflys.forest.converter.text.DefaultTextConverter;
|
||||
import com.dtflys.forest.utils.StringUtils;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Forest增强文本类型转换
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2024-05-06
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class EnhanceTextConverter extends DefaultTextConverter {
|
||||
private Object convert(byte[] source, Charset charset, String type) throws Exception {
|
||||
return convert(StringUtils.fromBytes(source, charset), type);
|
||||
}
|
||||
|
||||
private Object convert(String source, String type) throws Exception {
|
||||
switch (type) {
|
||||
case "boolean":
|
||||
case "java.lang.Boolean":
|
||||
return Boolean.valueOf(source);
|
||||
case "int":
|
||||
case "java.lang.Integer":
|
||||
return Integer.valueOf(source);
|
||||
case "long":
|
||||
case "java.lang.Long":
|
||||
return Long.valueOf(source);
|
||||
case "float":
|
||||
case "java.lang.Float":
|
||||
return Float.valueOf(source);
|
||||
case "double":
|
||||
case "java.lang.Double":
|
||||
return Double.valueOf(source);
|
||||
default:
|
||||
throw new Exception("the source may not be primary type");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T convertToJavaObject(String source, Type targetType) {
|
||||
try {
|
||||
return (T) convert(source, targetType.getTypeName());
|
||||
} catch (Exception e) {
|
||||
return super.convertToJavaObject(source, targetType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T convertToJavaObject(byte[] source, Class<T> targetType, Charset charset) {
|
||||
try {
|
||||
return (T) convert(source, charset, targetType.getName());
|
||||
} catch (Exception e) {
|
||||
return super.convertToJavaObject(source, targetType, charset);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T convertToJavaObject(byte[] source, Type targetType, Charset charset) {
|
||||
try {
|
||||
return (T) convert(source, charset, targetType.getTypeName());
|
||||
} catch (Exception e) {
|
||||
return super.convertToJavaObject(source, targetType, charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.eshore.gringotts.forest.configuration;
|
||||
|
||||
import com.dtflys.forest.converter.json.ForestJacksonConverter;
|
||||
import com.dtflys.forest.converter.text.DefaultTextConverter;
|
||||
import com.dtflys.forest.springboot.annotation.ForestScan;
|
||||
import com.fasterxml.jackson.datatype.eclipsecollections.EclipseCollectionsModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-24
|
||||
*/
|
||||
@ForestScan(basePackages = {"com.eshore.gringotts.forest.service"})
|
||||
@Configuration
|
||||
public class ForestsConfiguration {
|
||||
@Bean
|
||||
public ForestJacksonConverter forestJacksonConverter() {
|
||||
ForestJacksonConverter converter = new ForestJacksonConverter();
|
||||
converter.getMapper().registerModule(new EclipseCollectionsModule());
|
||||
converter.getMapper().registerModule(new JavaTimeModule());
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultTextConverter defaultTextConverter() {
|
||||
return new EnhanceTextConverter();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.eshore.gringotts.forest.configuration;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.dtflys.forest.exceptions.ForestRuntimeException;
|
||||
import com.dtflys.forest.http.ForestQueryMap;
|
||||
import com.dtflys.forest.http.ForestRequest;
|
||||
import com.dtflys.forest.http.ForestResponse;
|
||||
import com.dtflys.forest.interceptor.Interceptor;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.eclipse.collections.api.factory.Lists;
|
||||
import org.eclipse.collections.api.list.MutableList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 指标
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2024-01-31
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Component
|
||||
public class MetricsInterceptor implements Interceptor<Object> {
|
||||
public static final String FOREST_SEND_REQUEST = "service_forest_send_request";
|
||||
public static final String FOREST_SEND_REQUEST_SECONDS = "service_forest_send_request_seconds";
|
||||
private static final Logger logger = LoggerFactory.getLogger(MetricsInterceptor.class);
|
||||
private static final String PARSED_TAGS = "parsed_tags";
|
||||
private final MeterRegistry meterRegistry;
|
||||
|
||||
public MetricsInterceptor(MeterRegistry meterRegistry) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
private Iterable<Tag> parseTags(ForestRequest<?> request) {
|
||||
MutableList<Tag> tags = Lists.mutable.of(
|
||||
Tag.of("host", request.getHost()),
|
||||
Tag.of("port", String.valueOf(request.getPort())),
|
||||
Tag.of("path", request.getPath()),
|
||||
Tag.of("schema", request.getScheme())
|
||||
);
|
||||
ForestQueryMap query = request.getQuery();
|
||||
if (ObjectUtil.isNotEmpty(query)) {
|
||||
for (Map.Entry<String, Object> entry : query.entrySet()) {
|
||||
tags.add(Tag.of("query_" + entry.getKey(), String.valueOf(entry.getValue())));
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
private void increaseCounter(Integer code, MutableList<Tag> tags) {
|
||||
meterRegistry.counter(
|
||||
MetricsInterceptor.FOREST_SEND_REQUEST,
|
||||
tags.with(Tag.of("code", String.valueOf(code)))
|
||||
).increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeExecute(ForestRequest request) {
|
||||
addAttribute(request, PARSED_TAGS, parseTags(request));
|
||||
return Interceptor.super.beforeExecute(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterExecute(ForestRequest request, ForestResponse response) {
|
||||
Interceptor.super.afterExecute(request, response);
|
||||
|
||||
MutableList<Tag> tags = (MutableList<Tag>) getAttribute(request, PARSED_TAGS);
|
||||
meterRegistry.timer(FOREST_SEND_REQUEST_SECONDS, tags)
|
||||
.record(response.getTimeAsMillisecond(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Object data, ForestRequest request, ForestResponse response) {
|
||||
Interceptor.super.onSuccess(data, request, response);
|
||||
|
||||
MutableList<Tag> tags = (MutableList<Tag>) getAttribute(request, PARSED_TAGS);
|
||||
if (ObjectUtil.isNotNull(tags)) {
|
||||
increaseCounter(response.statusCode(), tags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) {
|
||||
Interceptor.super.onError(ex, request, response);
|
||||
|
||||
MutableList<Tag> tags = (MutableList<Tag>) getAttribute(request, PARSED_TAGS);
|
||||
if (ObjectUtil.isNotNull(tags)) {
|
||||
increaseCounter(response.statusCode(), tags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.eshore.gringotts.forest.configuration;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.dtflys.forest.http.ForestAddress;
|
||||
import com.dtflys.forest.http.ForestRequest;
|
||||
import com.dtflys.forest.interceptor.Interceptor;
|
||||
import java.net.URL;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2023-04-24
|
||||
*/
|
||||
@Component
|
||||
public class SpringCloudDiscoveryInterceptor implements Interceptor<Object> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringCloudDiscoveryInterceptor.class);
|
||||
|
||||
private final LoadBalancerClient loadBalancerClient;
|
||||
|
||||
public SpringCloudDiscoveryInterceptor(LoadBalancerClient loadBalancerClient) {
|
||||
this.loadBalancerClient = loadBalancerClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeExecute(ForestRequest request) {
|
||||
// Load
|
||||
URL url = URLUtil.url(request.getUrl());
|
||||
String host = url.getHost();
|
||||
if (StrUtil.isNotBlank(host)) {
|
||||
ServiceInstance instance = loadBalancerClient.choose(host);
|
||||
if (ObjectUtil.isNotNull(instance)) {
|
||||
request.setAddress(new ForestAddress(instance.getScheme(), instance.getHost(), instance.getPort()));
|
||||
}
|
||||
}
|
||||
// TODO 内网访问参数加密
|
||||
return Interceptor.super.beforeExecute(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.eshore.gringotts.forest.service;
|
||||
|
||||
import com.dtflys.forest.annotation.BaseRequest;
|
||||
import com.dtflys.forest.annotation.Body;
|
||||
import com.dtflys.forest.annotation.BodyType;
|
||||
import com.dtflys.forest.annotation.JSONBody;
|
||||
import com.dtflys.forest.annotation.Query;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
/**
|
||||
* 区块链服务
|
||||
*
|
||||
* @author lanyuanxiaoyao
|
||||
* @date 2024-11-15
|
||||
*/
|
||||
@BaseRequest(baseURL = "http://gringotts-chain")
|
||||
public interface ChainService {
|
||||
@GetMapping("/kv_datasource/create")
|
||||
String create();
|
||||
|
||||
@PostMapping("/kv_datasource/set")
|
||||
@BodyType("text")
|
||||
String set(@Query("address")String address, @Query("key") String key, @Body String json);
|
||||
|
||||
@GetMapping("/kv_datasource/get")
|
||||
String get(@Query("address")String address, @Query("key") String key);
|
||||
}
|
||||
Reference in New Issue
Block a user