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