params = buildParams(apiRequest);
try {
return AlipaySignature.rsaCheckV2(params, publicKey, charset, signType);
+ } catch (SignException e) {
+ ErrorEnum errorEnum = e.getErrorEnum();
+ ErrorMeta errorMeta = errorEnum.getErrorMeta();
+ log.error("验签错误, code={}, subCode={}, apiRequest={}",
+ errorMeta.getCode(), errorMeta.getSubCode(), apiRequest, e);
+ throw new ApiException(errorEnum, apiRequestContext.getLocale());
} catch (Exception e) {
- log.error("RSA2解密异常, params={}", params, e);
- return false;
+ log.error("验签未知错误, apiRequest={}", apiRequest, e);
+ throw new ApiException(ErrorEnum.ISV_INVALID_SIGNATURE, apiRequestContext.getLocale());
}
}
diff --git a/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RequestUtil.java b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RequestUtil.java
new file mode 100644
index 00000000..fe4ae80f
--- /dev/null
+++ b/sop-index/sop-index-service/src/main/java/com/gitee/sop/index/util/RequestUtil.java
@@ -0,0 +1,53 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.gitee.sop.index.util;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class RequestUtil {
+ private static final String IP_UNKNOWN = "unknown";
+ private static final String IP_LOCAL = "127.0.0.1";
+ private static final int IP_LEN = 15;
+
+ /**
+ * 获取客户端IP
+ *
+ * @param request request
+ * @return 返回ip
+ */
+ public static String getIP(HttpServletRequest request) {
+ String ipAddress = request.getHeader("x-forwarded-for");
+ if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ipAddress == null || ipAddress.length() == 0 || IP_UNKNOWN.equalsIgnoreCase(ipAddress)) {
+ ipAddress = request.getRemoteAddr();
+ if (IP_LOCAL.equals(ipAddress)) {
+ // 根据网卡取本机配置的IP
+ try {
+ InetAddress inet = InetAddress.getLocalHost();
+ ipAddress = inet.getHostAddress();
+ } catch (UnknownHostException e) {
+ // ignore
+ }
+ }
+
+ }
+
+ // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+ if (ipAddress != null && ipAddress.length() > IP_LEN) {
+ if (ipAddress.indexOf(",") > 0) {
+ ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
+ }
+ }
+ return ipAddress;
+ }
+}
diff --git a/sop-index/sop-index-service/src/main/resources/application-dev.properties b/sop-index/sop-index-service/src/main/resources/application-dev.properties
index 171e376d..2b4ffeb8 100644
--- a/sop-index/sop-index-service/src/main/resources/application-dev.properties
+++ b/sop-index/sop-index-service/src/main/resources/application-dev.properties
@@ -1,5 +1,7 @@
-nacos.host=127.0.0.1:8848
+dubbo.registry.address=zookeeper://localhost:2181
-dubbo.protocol.name=dubbo
-dubbo.protocol.port=-1
-dubbo.registry.address=nacos://${nacos.host}
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.url=jdbc:h2:mem:test
+spring.sql.init.schema-locations=classpath:schema.sql
+spring.datasource.username=${mysql.username}
+spring.datasource.password=${mysql.password}
diff --git a/sop-index/sop-index-service/src/main/resources/application.properties b/sop-index/sop-index-service/src/main/resources/application.properties
index b92b78f3..d86b0ca5 100644
--- a/sop-index/sop-index-service/src/main/resources/application.properties
+++ b/sop-index/sop-index-service/src/main/resources/application.properties
@@ -1,3 +1,28 @@
spring.profiles.active=dev
spring.application.name=sop-index
server.port=8081
+
+####### dubbo config #######
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=-1
+# ### register config see:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/
+# ------
+# nacos://localhost:8848 Cluster config:nacos://localhost:8848?backup=localshot:8846,localshot:8847
+# zookeeper://localhost:2181 Cluster config:zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181
+# redis://localhost:6379 Cluster config:redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379
+# ------
+dubbo.registry.address=nacos://localhost:8848
+####### dubbo config end #######
+
+
+####### mysql config #######
+mysql.host=127.0.0.1:3306
+mysql.username=root
+mysql.password=root
+mysql.db=sop
+
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.url=jdbc:mysql://${mysql.host}/${mysql.db}?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
+spring.datasource.username=${mysql.username}
+spring.datasource.password=${mysql.password}
+####### mysql config end #######
diff --git a/sop-index/sop-index-service/src/main/resources/schema.sql b/sop-index/sop-index-service/src/main/resources/schema.sql
new file mode 100644
index 00000000..de994a50
--- /dev/null
+++ b/sop-index/sop-index-service/src/main/resources/schema.sql
@@ -0,0 +1,16 @@
+CREATE TABLE `api_info`
+(
+ `id` INTEGER PRIMARY KEY AUTO_INCREMENT,
+ `application` varchar(64) NOT NULL DEFAULT '' COMMENT '应用名称',
+ `api_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口名称',
+ `api_version` varchar(16) NOT NULL DEFAULT '1.0' COMMENT '版本号',
+ `interface_class_name` varchar(128) NOT NULL DEFAULT '' COMMENT '接口class',
+ `method_name` varchar(128) NOT NULL DEFAULT '' COMMENT '方法名称',
+ `param_name` varchar(128) NOT NULL DEFAULT '' COMMENT '参数名称',
+ `param_type_name` varchar(128) NOT NULL DEFAULT '' COMMENT '参数类型名称',
+ is_permission tinyint(4) NOT NULL DEFAULT '0' COMMENT '接口是否需要授权访问',
+ is_need_Token tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否需要appAuthToken',
+ api_status tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1-启用,0-禁用',
+ `add_time` datetime NOT NULL DEFAULT null,
+ `update_time` datetime NOT NULL DEFAULT null
+);
diff --git a/sop-registry/pom.xml b/sop-registry/pom.xml
new file mode 100644
index 00000000..18f3fb08
--- /dev/null
+++ b/sop-registry/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ com.gitee.sop
+ sop-parent
+ 5.0.0-SNAPSHOT
+
+
+ sop-registry
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.apache.dubbo
+ dubbo-dependencies-zookeeper-curator5
+ ${dubbo.version}
+ pom
+
+
+ logback-classic
+ ch.qos.logback
+
+
+ logback-core
+ ch.qos.logback
+
+
+ log4j
+ log4j
+
+
+ slf4j-log4j12
+ org.slf4j
+
+
+
+
+
+
diff --git a/sop-registry/readme.md b/sop-registry/readme.md
new file mode 100644
index 00000000..920f680f
--- /dev/null
+++ b/sop-registry/readme.md
@@ -0,0 +1,4 @@
+内置简单的注册中心,基于zookeeper,用来开发演示使用.
+
+生产环境不可使用!
+生产环境不可使用!
diff --git a/sop-registry/src/main/java/com/gitee/sop/registry/EmbeddedZooKeeper.java b/sop-registry/src/main/java/com/gitee/sop/registry/EmbeddedZooKeeper.java
new file mode 100644
index 00000000..562f3407
--- /dev/null
+++ b/sop-registry/src/main/java/com/gitee/sop/registry/EmbeddedZooKeeper.java
@@ -0,0 +1,309 @@
+
+/*
+ * Copyright 2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.gitee.sop.registry;
+
+import org.apache.zookeeper.server.ServerConfig;
+import org.apache.zookeeper.server.ZooKeeperServerMain;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.util.ErrorHandler;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.ServerSocket;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java
+ *
+ * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper.
+ *
+ * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for
+ * {@link org.springframework.xd.dirt.server.singlenode.SingleNodeApplication}
+ *
+ * @author Patrick Peralta
+ * @author Mark Fisher
+ * @author David Turanski
+ */
+public class EmbeddedZooKeeper implements SmartLifecycle {
+
+ private static final Random RANDOM = new Random();
+
+ /**
+ * Logger.
+ */
+ private static final Logger logger = LoggerFactory.getLogger(EmbeddedZooKeeper.class);
+
+ /**
+ * ZooKeeper client port. This will be determined dynamically upon startup.
+ */
+ private final int clientPort;
+
+ /**
+ * Whether to auto-start. Default is true.
+ */
+ private boolean autoStartup = true;
+
+ /**
+ * Lifecycle phase. Default is 0.
+ */
+ private int phase = 0;
+
+ /**
+ * Thread for running the ZooKeeper server.
+ */
+ private volatile Thread zkServerThread;
+
+ /**
+ * ZooKeeper server.
+ */
+ private volatile ZooKeeperServerMain zkServer;
+
+ /**
+ * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread.
+ */
+ private ErrorHandler errorHandler;
+
+ private boolean daemon = true;
+
+ /**
+ * Construct an EmbeddedZooKeeper with a random port.
+ */
+ public EmbeddedZooKeeper() {
+ clientPort = findRandomPort(30000, 65535);
+ }
+
+ /**
+ * Construct an EmbeddedZooKeeper with the provided port.
+ *
+ * @param clientPort port for ZooKeeper server to bind to
+ */
+ public EmbeddedZooKeeper(int clientPort, boolean daemon) {
+ this.clientPort = clientPort;
+ this.daemon = daemon;
+ }
+
+ /**
+ * Returns the port that clients should use to connect to this embedded server.
+ *
+ * @return dynamically determined client port
+ */
+ public int getClientPort() {
+ return this.clientPort;
+ }
+
+ /**
+ * Specify whether to start automatically. Default is true.
+ *
+ * @param autoStartup whether to start automatically
+ */
+ public void setAutoStartup(boolean autoStartup) {
+ this.autoStartup = autoStartup;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAutoStartup() {
+ return this.autoStartup;
+ }
+
+ /**
+ * Specify the lifecycle phase for the embedded server.
+ *
+ * @param phase the lifecycle phase
+ */
+ public void setPhase(int phase) {
+ this.phase = phase;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getPhase() {
+ return this.phase;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRunning() {
+ return (zkServerThread != null);
+ }
+
+ /**
+ * Start the ZooKeeper server in a background thread.
+ *
+ * Register an error handler via {@link #setErrorHandler} in order to handle
+ * any exceptions thrown during startup or execution.
+ */
+ @Override
+ public synchronized void start() {
+ if (zkServerThread == null) {
+ zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter");
+ zkServerThread.setDaemon(daemon);
+ zkServerThread.start();
+ }
+ }
+
+ /**
+ * Shutdown the ZooKeeper server.
+ */
+ @Override
+ public synchronized void stop() {
+ if (zkServerThread != null) {
+ // The shutdown method is protected...thus this hack to invoke it.
+ // This will log an exception on shutdown; see
+ // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details.
+ try {
+ Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown");
+ shutdown.setAccessible(true);
+ shutdown.invoke(zkServer);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ // It is expected that the thread will exit after
+ // the server is shutdown; this will block until
+ // the shutdown is complete.
+ try {
+ zkServerThread.join(5000);
+ zkServerThread = null;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ logger.warn("Interrupted while waiting for embedded ZooKeeper to exit");
+ // abandoning zk thread
+ zkServerThread = null;
+ }
+ }
+ }
+
+ /**
+ * Stop the server if running and invoke the callback when complete.
+ */
+ @Override
+ public void stop(Runnable callback) {
+ stop();
+ callback.run();
+ }
+
+ /**
+ * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none
+ * is provided, only error-level logging will occur.
+ *
+ * @param errorHandler the {@link ErrorHandler} to be invoked
+ */
+ public void setErrorHandler(ErrorHandler errorHandler) {
+ this.errorHandler = errorHandler;
+ }
+
+ /**
+ * Runnable implementation that starts the ZooKeeper server.
+ */
+ private class ServerRunnable implements Runnable {
+
+ @Override
+ public void run() {
+ try {
+ Properties properties = new Properties();
+ File file = new File(System.getProperty("java.io.tmpdir")
+ + File.separator + UUID.randomUUID());
+ file.deleteOnExit();
+ properties.setProperty("dataDir", file.getAbsolutePath());
+ properties.setProperty("clientPort", String.valueOf(clientPort));
+
+ QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();
+ quorumPeerConfig.parseProperties(properties);
+
+ zkServer = new ZooKeeperServerMain();
+ ServerConfig configuration = new ServerConfig();
+ configuration.readFrom(quorumPeerConfig);
+
+ System.setProperty("zookeeper.admin.enableServer", "false");
+
+ zkServer.runFromConfig(configuration);
+ } catch (Exception e) {
+ if (errorHandler != null) {
+ errorHandler.handleError(e);
+ } else {
+ logger.error("Exception running embedded ZooKeeper", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Workaround for SocketUtils.findRandomPort() deprecation.
+ *
+ * @param min min port
+ * @param max max port
+ * @return a random generated available port
+ */
+ private static int findRandomPort(int min, int max) {
+ if (min < 1024) {
+ throw new IllegalArgumentException("Max port shouldn't be less than 1024.");
+ }
+
+ if (max > 65535) {
+ throw new IllegalArgumentException("Max port shouldn't be greater than 65535.");
+ }
+
+ if (min > max) {
+ throw new IllegalArgumentException("Min port shouldn't be greater than max port.");
+ }
+
+ int port = 0;
+ int counter = 0;
+
+ // Workaround for legacy JDK doesn't support Random.nextInt(min, max).
+ List randomInts = RANDOM.ints(min, max + 1)
+ .limit(max - min)
+ .mapToObj(Integer::valueOf)
+ .collect(Collectors.toList());
+
+ do {
+ if (counter > max - min) {
+ throw new IllegalStateException("Unable to find a port between " + min + "-" + max);
+ }
+
+ port = randomInts.get(counter);
+ counter++;
+ } while (isPortInUse(port));
+
+ return port;
+ }
+
+ private static boolean isPortInUse(int port) {
+ try (ServerSocket ignored = new ServerSocket(port)) {
+ return false;
+ } catch (IOException e) {
+ // continue
+ }
+ return true;
+ }
+}
diff --git a/sop-registry/src/main/java/com/gitee/sop/registry/RegistryMain.java b/sop-registry/src/main/java/com/gitee/sop/registry/RegistryMain.java
new file mode 100644
index 00000000..27c3fb02
--- /dev/null
+++ b/sop-registry/src/main/java/com/gitee/sop/registry/RegistryMain.java
@@ -0,0 +1,12 @@
+package com.gitee.sop.registry;
+
+/**
+ * @author 六如
+ */
+public class RegistryMain {
+ public static void main(String[] args) {
+ int zkPort = 2181;
+ System.out.println("启动内置zookeeper注册中心(仅在开发环境下使用),port=" + zkPort);
+ new EmbeddedZooKeeper(zkPort, false).start();
+ }
+}
diff --git a/sop-spring-boot-starter/pom.xml b/sop-spring-boot-starter/pom.xml
index 3dab4fa5..2b1cefea 100644
--- a/sop-spring-boot-starter/pom.xml
+++ b/sop-spring-boot-starter/pom.xml
@@ -21,12 +21,6 @@
5.0.0-SNAPSHOT