|
@@ -0,0 +1,247 @@
|
|
|
|
|
+package com.yiidata.intergration.proxy;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import com.google.common.base.Charsets;
|
|
|
|
|
+import com.google.common.collect.Lists;
|
|
|
|
|
+import com.google.common.io.Files;
|
|
|
|
|
+import com.yiidata.intergration.api.SwaggerController;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.cli.CommandLine;
|
|
|
|
|
+import org.apache.commons.cli.GnuParser;
|
|
|
|
|
+import org.apache.commons.cli.HelpFormatter;
|
|
|
|
|
+import org.apache.commons.cli.Options;
|
|
|
|
|
+import org.apache.commons.cli.ParseException;
|
|
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
|
|
+import org.eclipse.jetty.server.CustomRequestLog;
|
|
|
|
|
+import org.eclipse.jetty.server.RequestLog;
|
|
|
|
|
+import org.eclipse.jetty.server.Server;
|
|
|
|
|
+import org.eclipse.jetty.server.Slf4jRequestLogWriter;
|
|
|
|
|
+import org.eclipse.jetty.server.handler.HandlerCollection;
|
|
|
|
|
+import org.eclipse.jetty.server.handler.RequestLogHandler;
|
|
|
|
|
+import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
|
|
|
|
+import org.eclipse.jetty.util.resource.PathResource;
|
|
|
|
|
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|
|
|
|
+import org.eclipse.jetty.util.thread.ThreadPool;
|
|
|
|
|
+import org.eclipse.jetty.xml.XmlConfiguration;
|
|
|
|
|
+import org.yaml.snakeyaml.Yaml;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.File;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.lang.reflect.Array;
|
|
|
|
|
+import java.net.InetSocketAddress;
|
|
|
|
|
+import java.net.URL;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Collection;
|
|
|
|
|
+import java.util.HashSet;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Optional;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * <pre>
|
|
|
|
|
+ *
|
|
|
|
|
+ * Created by zhenqin.
|
|
|
|
|
+ * User: zhenqin
|
|
|
|
|
+ * Date: 2019/11/13
|
|
|
|
|
+ * Time: 14:51
|
|
|
|
|
+ * Vendor: yiidata.com
|
|
|
|
|
+ * To change this template use File | Settings | File Templates.
|
|
|
|
|
+ *
|
|
|
|
|
+ * </pre>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author zhenqin
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+public class YmlConfiguration {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取 AMC 部署的目录
|
|
|
|
|
+ * @return 返回 AMC 部署的目录
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getAppHome(){
|
|
|
|
|
+ /*
|
|
|
|
|
+ * modify By ZhenQin AT:2018-1-5
|
|
|
|
|
+ * 增加了先从环境变量中读取该参数,再从 系统JVM 变量中读取
|
|
|
|
|
+ */
|
|
|
|
|
+ String spHome = System.getenv("APP_HOME");
|
|
|
|
|
+ if(StringUtils.isBlank(spHome)) {
|
|
|
|
|
+ spHome = System.getProperty("app.home");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 返回当前目录
|
|
|
|
|
+ if(StringUtils.isBlank(spHome)){
|
|
|
|
|
+ spHome = ".";
|
|
|
|
|
+ }
|
|
|
|
|
+ return spHome;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 返回 jvm 加載的 ClassLoader
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static ClassLoader getClassLoader(){
|
|
|
|
|
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
|
|
|
|
+ if(classLoader == null){
|
|
|
|
|
+ classLoader = ProxyAppServer.class.getClassLoader();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return classLoader;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 獲取項目類路徑的 Classpath
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String getClasspath(){
|
|
|
|
|
+ URL resource = getClassLoader().getResource("");
|
|
|
|
|
+ if(resource != null){
|
|
|
|
|
+ String classpath = resource.getPath();
|
|
|
|
|
+ return classpath;
|
|
|
|
|
+ }
|
|
|
|
|
+ return getAppHome() + File.separator + "etc";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从 conf 中获得 整形 值
|
|
|
|
|
+ * @param conf
|
|
|
|
|
+ * @param key
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private Integer getInteger(Map<String, Object> conf, String key) {
|
|
|
|
|
+ return getInteger(conf, key, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private Integer getInteger(Map<String, Object> conf, String key, Integer defaultValue) {
|
|
|
|
|
+ String[] keySplits = key.split("\\.");
|
|
|
|
|
+ if(keySplits.length >= 2) {
|
|
|
|
|
+ Object value = conf.get(keySplits[0]);
|
|
|
|
|
+ // 内层的值如果取到 null 了,说明配置中没有那么深的层次
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!(value instanceof Map)) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String[] ckeys = new String[keySplits.length -1];
|
|
|
|
|
+ System.arraycopy(keySplits, 1, ckeys, 0, ckeys.length);
|
|
|
|
|
+ return getInteger((Map)value, StringUtils.join(ckeys, "."), defaultValue);
|
|
|
|
|
+ }
|
|
|
|
|
+ Object value = conf.get(key);
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ return value instanceof Number ? ((Number) value).intValue() : Integer.parseInt((String) value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从 conf 中获取 字符串值
|
|
|
|
|
+ * @param conf
|
|
|
|
|
+ * @param key
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private String getString(Map<String, Object> conf, String key) {
|
|
|
|
|
+ return getString(conf, key, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private String getString(Map<String, Object> conf, String key, String defaultValue) {
|
|
|
|
|
+ String[] keySplits = key.split("\\.");
|
|
|
|
|
+ if(keySplits.length >= 2) {
|
|
|
|
|
+ Object value = conf.get(keySplits[0]);
|
|
|
|
|
+ // 内层的值如果取到 null 了,说明配置中没有那么深的层次
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!(value instanceof Map)) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String[] ckeys = new String[keySplits.length -1];
|
|
|
|
|
+ System.arraycopy(keySplits, 1, ckeys, 0, ckeys.length);
|
|
|
|
|
+ return getString((Map)value, StringUtils.join(ckeys, "."), defaultValue);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Object value = conf.get(key);
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ return value instanceof String ? (String) value : String.valueOf(value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取 数组 配置
|
|
|
|
|
+ * @param conf
|
|
|
|
|
+ * @param key
|
|
|
|
|
+ * @param <T>
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ private <T> Collection<T> getArray(Map<String, Object> conf, String key) {
|
|
|
|
|
+ return getArray(conf, key, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private <T> Collection<T> getArray(Map<String, Object> conf, String key, Collection<T> defaultValue) {
|
|
|
|
|
+ String[] keySplits = key.split("\\.");
|
|
|
|
|
+ if(keySplits.length >= 2) {
|
|
|
|
|
+ Object value = conf.get(keySplits[0]);
|
|
|
|
|
+ // 内层的值如果取到 null 了,说明配置中没有那么深的层次
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!(value instanceof Map)) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+ String[] ckeys = new String[keySplits.length -1];
|
|
|
|
|
+ System.arraycopy(keySplits, 1, ckeys, 0, ckeys.length);
|
|
|
|
|
+ return getArray((Map)value, StringUtils.join(ckeys, "."), defaultValue);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Object value = conf.get(key);
|
|
|
|
|
+ if(value == null) {
|
|
|
|
|
+ return defaultValue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(value instanceof Collection) {
|
|
|
|
|
+ return (Collection) value;
|
|
|
|
|
+ } else if(value instanceof Array) {
|
|
|
|
|
+ ArrayList objects = Lists.newArrayList();
|
|
|
|
|
+ CollectionUtils.addAll(objects, (Object[])value);
|
|
|
|
|
+ return (Collection) objects;
|
|
|
|
|
+ }
|
|
|
|
|
+ return (Collection) Lists.newArrayList(value);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 支持 JSON 和 Yml 两种配置
|
|
|
|
|
+ * @param configFilePath
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @throws IOException
|
|
|
|
|
+ */
|
|
|
|
|
+ public Map<String, Object> parseConfig(String configFilePath) throws IOException {
|
|
|
|
|
+ String configContent = Files.asCharSource(new File(configFilePath), Charsets.UTF_8).read();
|
|
|
|
|
+ if(configFilePath.endsWith(".json")) {
|
|
|
|
|
+ JSONObject json = JSON.parseObject(configContent);
|
|
|
|
|
+ return json;
|
|
|
|
|
+ } else if(configFilePath.endsWith(".yml") || configFilePath.endsWith(".yaml")) {
|
|
|
|
|
+ Yaml yaml = new Yaml();
|
|
|
|
|
+ Object ret = yaml.load(configContent);
|
|
|
|
|
+ return (Map)ret;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ throw new IllegalStateException("unknown type config file: " + configFilePath);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|