parent
e1e7b2c738
commit
5bd787b7e3
@ -1,27 +0,0 @@ |
|||||||
package com.gitee.sop.servercommon.bean; |
|
||||||
|
|
||||||
import org.springframework.core.env.Environment; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author thc |
|
||||||
*/ |
|
||||||
public class EnvironmentContext { |
|
||||||
|
|
||||||
private static Environment environment; |
|
||||||
|
|
||||||
public static Environment getEnvironment() { |
|
||||||
return environment; |
|
||||||
} |
|
||||||
|
|
||||||
public static void setEnvironment(Environment environment) { |
|
||||||
EnvironmentContext.environment = environment; |
|
||||||
} |
|
||||||
|
|
||||||
public static String getProfile(Environment env) { |
|
||||||
return env.getProperty("spring.profiles.active", "default"); |
|
||||||
} |
|
||||||
|
|
||||||
public static String getProfile() { |
|
||||||
return getProfile(environment); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,11 @@ |
|||||||
|
package com.gitee.sop.servercommon.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
public class ServiceConstants { |
||||||
|
/** |
||||||
|
* zookeeper存放接口路由信息的根目录 |
||||||
|
*/ |
||||||
|
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route"; |
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
package com.gitee.sop.servercommon.bean; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
import org.apache.commons.lang.math.NumberUtils; |
||||||
|
import org.apache.curator.framework.CuratorFramework; |
||||||
|
import org.apache.curator.framework.CuratorFrameworkFactory; |
||||||
|
import org.apache.curator.retry.ExponentialBackoffRetry; |
||||||
|
import org.springframework.core.env.Environment; |
||||||
|
|
||||||
|
import java.io.Closeable; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Getter |
||||||
|
public class ZookeeperTool implements Closeable { |
||||||
|
|
||||||
|
private CuratorFramework client; |
||||||
|
private Environment environment; |
||||||
|
|
||||||
|
public ZookeeperTool(Environment environment) { |
||||||
|
this.environment = environment; |
||||||
|
initZookeeperClient(environment); |
||||||
|
} |
||||||
|
|
||||||
|
public void initZookeeperClient(Environment environment) { |
||||||
|
String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); |
||||||
|
if (StringUtils.isBlank(zookeeperServerAddr)) { |
||||||
|
throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); |
||||||
|
} |
||||||
|
String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); |
||||||
|
String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); |
||||||
|
log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", |
||||||
|
zookeeperServerAddr, baseSleepTimeMs, maxRetries); |
||||||
|
CuratorFramework client = CuratorFrameworkFactory.builder() |
||||||
|
.connectString(zookeeperServerAddr) |
||||||
|
.retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) |
||||||
|
.build(); |
||||||
|
|
||||||
|
client.start(); |
||||||
|
|
||||||
|
this.client = client; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isPathExist(String path) { |
||||||
|
try { |
||||||
|
return client.checkExists().forPath(path) != null; |
||||||
|
} catch (Exception e) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建path,如果path存在不报错,静默返回path名称 |
||||||
|
* |
||||||
|
* @param path |
||||||
|
* @param data |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public String createPath(String path, String data) throws Exception { |
||||||
|
if (isPathExist(path)) { |
||||||
|
return path; |
||||||
|
} |
||||||
|
return getClient().create() |
||||||
|
// 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点
|
||||||
|
.creatingParentContainersIfNeeded() |
||||||
|
.forPath(path, data.getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 新建或保存节点 |
||||||
|
* |
||||||
|
* @param path |
||||||
|
* @param data |
||||||
|
* @return 返回path |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public String createOrUpdateData(String path, String data) throws Exception { |
||||||
|
return getClient().create() |
||||||
|
// 如果节点存在则Curator将会使用给出的数据设置这个节点的值
|
||||||
|
.orSetData() |
||||||
|
// 如果指定节点的父节点不存在,则Curator将会自动级联创建父节点
|
||||||
|
.creatingParentContainersIfNeeded() |
||||||
|
.forPath(path, data.getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void close() throws IOException { |
||||||
|
if (this.client != null) { |
||||||
|
this.client.close(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
package com.gitee.sop.servercommon.configuration; |
||||||
|
|
||||||
|
import com.gitee.easyopen.doc.ApiDocHolder; |
||||||
|
import com.gitee.sop.servercommon.swagger.SwaggerValidator; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* 文档支持 |
||||||
|
* @author thc |
||||||
|
*/ |
||||||
|
public abstract class EasyopenDocSupportController { |
||||||
|
|
||||||
|
private SwaggerValidator swaggerValidator; |
||||||
|
|
||||||
|
public abstract String getDocTitle(); |
||||||
|
|
||||||
|
public EasyopenDocSupportController() { |
||||||
|
swaggerValidator = new SwaggerValidator(this.swaggerAccessProtected()); |
||||||
|
} |
||||||
|
|
||||||
|
@RequestMapping("/v2/api-docs") |
||||||
|
@ResponseBody |
||||||
|
public Map<String, Object> getDocInfo(HttpServletRequest request, HttpServletResponse response) throws IOException { |
||||||
|
if (swaggerValidator.swaggerAccessProtected() && !swaggerValidator.validate(request)) { |
||||||
|
swaggerValidator.writeForbidden(response); |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, Object> context = this.getContext(); |
||||||
|
context.put("easyopen", "1.16.3"); |
||||||
|
context.put("apiModules", ApiDocHolder.getApiDocBuilder().getApiModules()); |
||||||
|
context.put("title", getDocTitle()); |
||||||
|
return context; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, Object> getContext() { |
||||||
|
return new HashMap<>(8); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* swagger访问是否加密保护 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
protected boolean swaggerAccessProtected() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,16 +0,0 @@ |
|||||||
package com.gitee.sop.servercommon.swagger; |
|
||||||
|
|
||||||
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager; |
|
||||||
import springfox.documentation.spring.web.scanners.ApiDescriptionReader; |
|
||||||
import springfox.documentation.spring.web.scanners.ApiListingScanner; |
|
||||||
import springfox.documentation.spring.web.scanners.ApiModelReader; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author tanghc |
|
||||||
*/ |
|
||||||
public class ApiListingScannerExt extends ApiListingScanner { |
|
||||||
public ApiListingScannerExt(ApiDescriptionReader apiDescriptionReader, ApiModelReader apiModelReader, DocumentationPluginsManager pluginsManager) { |
|
||||||
super(apiDescriptionReader, apiModelReader, pluginsManager); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,53 @@ |
|||||||
|
package com.gitee.sop.servercommon.swagger; |
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
import org.springframework.util.DigestUtils; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.PrintWriter; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
public class SwaggerValidator { |
||||||
|
|
||||||
|
private String secret = "b749a2ec000f4f29"; |
||||||
|
|
||||||
|
private boolean swaggerAccessProtected = true; |
||||||
|
|
||||||
|
public SwaggerValidator(boolean swaggerAccessProtected) { |
||||||
|
this.swaggerAccessProtected = swaggerAccessProtected; |
||||||
|
} |
||||||
|
|
||||||
|
public SwaggerValidator() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* swagger访问是否加密保护 |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public boolean swaggerAccessProtected() { |
||||||
|
return swaggerAccessProtected; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean validate(HttpServletRequest request) { |
||||||
|
String time = request.getParameter("time"); |
||||||
|
String sign = request.getParameter("sign"); |
||||||
|
if (StringUtils.isAnyBlank(time, sign)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
String source = secret + time + secret; |
||||||
|
String serverSign = DigestUtils.md5DigestAsHex(source.getBytes()); |
||||||
|
return serverSign.equals(sign); |
||||||
|
} |
||||||
|
|
||||||
|
public void writeForbidden(HttpServletResponse response) throws IOException { |
||||||
|
response.setContentType("text/palin;charset=UTF-8"); |
||||||
|
response.setStatus(403); |
||||||
|
PrintWriter printWriter = response.getWriter(); |
||||||
|
printWriter.write("access forbidden"); |
||||||
|
printWriter.flush(); |
||||||
|
} |
||||||
|
} |
@ -1,28 +0,0 @@ |
|||||||
package com.gitee.easyopen.server.config; |
|
||||||
|
|
||||||
import com.gitee.easyopen.doc.ApiDocHolder; |
|
||||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||||
import org.springframework.web.bind.annotation.ResponseBody; |
|
||||||
|
|
||||||
import java.util.HashMap; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
public abstract class BaseSopDocController { |
|
||||||
|
|
||||||
public abstract String getDocTitle(); |
|
||||||
|
|
||||||
@RequestMapping("/v2/api-docs") |
|
||||||
@ResponseBody |
|
||||||
public Map<String, Object> getDocInfo() { |
|
||||||
Map<String, Object> context = this.getContext(); |
|
||||||
context.put("easyopen", "1.16.3"); |
|
||||||
context.put("apiModules", ApiDocHolder.getApiDocBuilder().getApiModules()); |
|
||||||
context.put("title", getDocTitle()); |
|
||||||
return context; |
|
||||||
} |
|
||||||
|
|
||||||
public Map<String, Object> getContext() { |
|
||||||
return new HashMap<>(8); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,17 @@ |
|||||||
|
eureka: |
||||||
|
client: |
||||||
|
fetch-registry: false |
||||||
|
# 不注册自己 |
||||||
|
register-with-eureka: false |
||||||
|
serviceUrl: |
||||||
|
defaultZone: http://${eureka.host}:${eureka.port}/eureka/ |
||||||
|
# 注册中心地址 |
||||||
|
host: localhost |
||||||
|
port: 1111 |
||||||
|
|
||||||
|
server: |
||||||
|
port: 1111 |
||||||
|
|
||||||
|
spring: |
||||||
|
application: |
||||||
|
name: sop-registry |
@ -1,12 +0,0 @@ |
|||||||
spring.application.name=sop-registry |
|
||||||
server.port=1111 |
|
||||||
|
|
||||||
# ---- eureka注册中心 ---- |
|
||||||
# 不注册自己 |
|
||||||
eureka.client.register-with-eureka=false |
|
||||||
eureka.client.fetch-registry=false |
|
||||||
# 注册中心地址 |
|
||||||
eureka.host=localhost |
|
||||||
eureka.port=1111 |
|
||||||
eureka.client.serviceUrl.defaultZone=http://${eureka.host}:${eureka.port}/eureka/ |
|
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
spring: |
||||||
|
profiles: |
||||||
|
active: dev |
@ -0,0 +1,11 @@ |
|||||||
|
package com.gitee.sop.websiteserver.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
public class WebsiteConstants { |
||||||
|
/** |
||||||
|
* zookeeper存放接口路由信息的根目录 |
||||||
|
*/ |
||||||
|
public static final String SOP_SERVICE_ROUTE_PATH = "/com.gitee.sop.route"; |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package com.gitee.sop.websiteserver.bean; |
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
import org.apache.commons.lang.math.NumberUtils; |
||||||
|
import org.apache.curator.framework.CuratorFramework; |
||||||
|
import org.apache.curator.framework.CuratorFrameworkFactory; |
||||||
|
import org.apache.curator.framework.recipes.cache.TreeCache; |
||||||
|
import org.apache.curator.framework.recipes.cache.TreeCacheListener; |
||||||
|
import org.apache.curator.retry.ExponentialBackoffRetry; |
||||||
|
import org.springframework.core.env.Environment; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
public class ZookeeperContext { |
||||||
|
|
||||||
|
private static CuratorFramework client; |
||||||
|
|
||||||
|
public static void setEnvironment(Environment environment) { |
||||||
|
Assert.notNull(environment, "environment不能为null"); |
||||||
|
initZookeeperClient(environment); |
||||||
|
} |
||||||
|
|
||||||
|
public synchronized static void initZookeeperClient(Environment environment) { |
||||||
|
if (client != null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String zookeeperServerAddr = environment.getProperty("spring.cloud.zookeeper.connect-string"); |
||||||
|
if (StringUtils.isBlank(zookeeperServerAddr)) { |
||||||
|
throw new RuntimeException("未指定spring.cloud.zookeeper.connect-string参数"); |
||||||
|
} |
||||||
|
String baseSleepTimeMs = environment.getProperty("spring.cloud.zookeeper.baseSleepTimeMs"); |
||||||
|
String maxRetries = environment.getProperty("spring.cloud.zookeeper.maxRetries"); |
||||||
|
log.info("初始化zookeeper客户端,zookeeperServerAddr:{}, baseSleepTimeMs:{}, maxRetries:{}", |
||||||
|
zookeeperServerAddr, baseSleepTimeMs, maxRetries); |
||||||
|
CuratorFramework client = CuratorFrameworkFactory.builder() |
||||||
|
.connectString(zookeeperServerAddr) |
||||||
|
.retryPolicy(new ExponentialBackoffRetry(NumberUtils.toInt(baseSleepTimeMs, 3000), NumberUtils.toInt(maxRetries, 3))) |
||||||
|
.build(); |
||||||
|
|
||||||
|
client.start(); |
||||||
|
|
||||||
|
setClient(client); |
||||||
|
} |
||||||
|
|
||||||
|
public static String getRouteRootPath() { |
||||||
|
return WebsiteConstants.SOP_SERVICE_ROUTE_PATH; |
||||||
|
} |
||||||
|
|
||||||
|
public static CuratorFramework getClient() { |
||||||
|
return client; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setClient(CuratorFramework client) { |
||||||
|
ZookeeperContext.client = client; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 监听子节点,可以自定义层级 |
||||||
|
* @param parentPath 父节点路径 |
||||||
|
* @param maxDepth 层级,从1开始。比如当前监听节点/t1,目录最深为/t1/t2/t3/t4,则maxDepth=3,说明下面3级子目录全 |
||||||
|
* @param listener |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static void listenChildren(String parentPath, int maxDepth, TreeCacheListener listener) throws Exception { |
||||||
|
final TreeCache treeCache = TreeCache |
||||||
|
.newBuilder(client, parentPath) |
||||||
|
.setCacheData(true) |
||||||
|
.setMaxDepth(maxDepth) |
||||||
|
.build(); |
||||||
|
|
||||||
|
treeCache.getListenable().addListener(listener); |
||||||
|
//没有开启模式作为入参的方法
|
||||||
|
treeCache.start(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue