diff --git a/pom.xml b/pom.xml
index 6499141..dfb2870 100644
--- a/pom.xml
+++ b/pom.xml
@@ -285,5 +285,17 @@
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+ true
+
+
+
+
diff --git a/readme.md b/readme.md
index 7c6b272..5dc3afa 100644
--- a/readme.md
+++ b/readme.md
@@ -114,6 +114,12 @@ Maven依赖为
tracker-list: #TrackerList参数,支持多个
- 192.168.1.105:22122
- 192.168.1.106:22122
+ storage-node: # 存储节点,处理FASTDFS内网STORAGE IP 映射问题
+ ip-mapping:
+ group1:
+ 172.30.0.1-23000: 192.168.178.128-23000
+ group2:
+ 172.30.0.1-23001: 192.168.178.128-23001
### 4.连接池的管理参数
diff --git a/src/main/java/com/github/tobato/fastdfs/FdfsClientConstants.java b/src/main/java/com/github/tobato/fastdfs/FdfsClientConstants.java
index f2774e7..d931d01 100644
--- a/src/main/java/com/github/tobato/fastdfs/FdfsClientConstants.java
+++ b/src/main/java/com/github/tobato/fastdfs/FdfsClientConstants.java
@@ -31,4 +31,11 @@ private FdfsClientConstants() {
*/
public static final String POOL_CONFIG_PREFIX = "fdfs.pool";
+ /**
+ * 存储节点配置
+ */
+ public static final String STORAGE_CONFIG_PREFIX = "fdfs.storage-node";
+
+
+
}
diff --git a/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeConfig.java b/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeConfig.java
new file mode 100644
index 0000000..d070960
--- /dev/null
+++ b/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeConfig.java
@@ -0,0 +1,44 @@
+package com.github.tobato.fastdfs.domain.fdfs;
+
+import com.github.tobato.fastdfs.FdfsClientConstants;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 存储节点配置参数
+ * @author Rong.Jia
+ * @date 2021/01/24 10:38
+ */
+@Component
+@ConfigurationProperties(prefix = FdfsClientConstants.STORAGE_CONFIG_PREFIX)
+public class StorageNodeConfig {
+
+ /***
+ * storage real IP and port mapping to proxy IP and port
+ *
+ * 格式:
+ * (yml文件)
+ * group0:
+ * 172.10.0.3-23000: 192.168.130.14-23000
+ * 172.10.0.4-23000: 192.168.130.13-23000
+ *
+ *
+ */
+ private Map> ipMapping;
+
+ public Map> getIpMapping() {
+ return ipMapping;
+ }
+
+ public void setIpMapping(Map> ipMapping) {
+ this.ipMapping = ipMapping;
+ }
+
+
+}
diff --git a/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeReal.java b/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeReal.java
new file mode 100644
index 0000000..865e0ca
--- /dev/null
+++ b/src/main/java/com/github/tobato/fastdfs/domain/fdfs/StorageNodeReal.java
@@ -0,0 +1,61 @@
+package com.github.tobato.fastdfs.domain.fdfs;
+
+import java.io.Serializable;
+
+/**
+ * 节点的 真实IP,端口信息
+ * @author Rong.Jia
+ * @date 2021/01/24 12:56
+ */
+public class StorageNodeReal implements Serializable {
+
+ private static final long serialVersionUID = 6856298300479910590L;
+
+ /**
+ * IP
+ */
+ private String ip;
+
+ /**
+ * 端口
+ */
+ private Integer port;
+
+ /**
+ * 组名
+ */
+ private String groupName;
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+
+ public Integer getPort() {
+ return port;
+ }
+
+ public void setPort(Integer port) {
+ this.port = port;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ @Override
+ public String toString() {
+ return "StorageNodeReal{" +
+ "ip='" + ip + '\'' +
+ ", port=" + port +
+ ", groupName='" + groupName + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/com/github/tobato/fastdfs/service/DefaultTrackerClient.java b/src/main/java/com/github/tobato/fastdfs/service/DefaultTrackerClient.java
index d4895de..ada12be 100644
--- a/src/main/java/com/github/tobato/fastdfs/service/DefaultTrackerClient.java
+++ b/src/main/java/com/github/tobato/fastdfs/service/DefaultTrackerClient.java
@@ -1,16 +1,23 @@
package com.github.tobato.fastdfs.service;
+import com.github.tobato.fastdfs.domain.conn.FdfsConnectionManager;
import com.github.tobato.fastdfs.domain.conn.TrackerConnectionManager;
-import com.github.tobato.fastdfs.domain.fdfs.GroupState;
-import com.github.tobato.fastdfs.domain.fdfs.StorageNode;
-import com.github.tobato.fastdfs.domain.fdfs.StorageNodeInfo;
-import com.github.tobato.fastdfs.domain.fdfs.StorageState;
+import com.github.tobato.fastdfs.domain.fdfs.*;
import com.github.tobato.fastdfs.domain.proto.tracker.*;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import java.lang.reflect.Field;
+import java.util.Arrays;
import java.util.List;
+import java.util.Map;
/**
* 目录服务客户端默认实现
@@ -20,16 +27,24 @@
@Service
public class DefaultTrackerClient implements TrackerClient {
+ /**
+ * 日志
+ */
+ protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultTrackerClient.class);
+
@Autowired
private TrackerConnectionManager trackerConnectionManager;
+ @Autowired
+ private StorageNodeConfig storageNodeConfig;
+
/**
* 获取存储节点
*/
@Override
public StorageNode getStoreStorage() {
TrackerGetStoreStorageCommand command = new TrackerGetStoreStorageCommand();
- return trackerConnectionManager.executeFdfsTrackerCmd(command);
+ return getStorageNode(trackerConnectionManager.executeFdfsTrackerCmd(command));
}
/**
@@ -44,7 +59,7 @@ public StorageNode getStoreStorage(String groupName) {
command = new TrackerGetStoreStorageCommand(groupName);
}
- return trackerConnectionManager.executeFdfsTrackerCmd(command);
+ return getStorageNode(trackerConnectionManager.executeFdfsTrackerCmd(command));
}
/**
@@ -53,7 +68,7 @@ public StorageNode getStoreStorage(String groupName) {
@Override
public StorageNodeInfo getFetchStorage(String groupName, String filename) {
TrackerGetFetchStorageCommand command = new TrackerGetFetchStorageCommand(groupName, filename, false);
- return trackerConnectionManager.executeFdfsTrackerCmd(command);
+ return getStorageNode(trackerConnectionManager.executeFdfsTrackerCmd(command));
}
/**
@@ -62,7 +77,7 @@ public StorageNodeInfo getFetchStorage(String groupName, String filename) {
@Override
public StorageNodeInfo getUpdateStorage(String groupName, String filename) {
TrackerGetFetchStorageCommand command = new TrackerGetFetchStorageCommand(groupName, filename, true);
- return trackerConnectionManager.executeFdfsTrackerCmd(command);
+ return getStorageNode(trackerConnectionManager.executeFdfsTrackerCmd(command));
}
/**
@@ -101,4 +116,85 @@ public void deleteStorage(String groupName, String storageIpAddr) {
trackerConnectionManager.executeFdfsTrackerCmd(command);
}
+ /**
+ * 获取 存储节点
+ * @param storageNode 存储节点
+ * @return 存储节点信息
+ */
+ private T getStorageNode(T storageNode) {
+
+ Object groupNameObj = getFieldValue(storageNode, "groupName");
+ Object ipObj = getFieldValue(storageNode, "ip");
+ Object portObj = getFieldValue(storageNode, "port");
+
+ if (!ObjectUtils.isEmpty(groupNameObj) && !ObjectUtils.isEmpty(ipObj)
+ && !ObjectUtils.isEmpty(portObj)) {
+ String groupName = String.valueOf(groupNameObj);
+ String ip = String.valueOf(ipObj);
+ Integer port = Integer.parseInt(String.valueOf(portObj));
+
+ StorageNodeReal storageNodeReal = getStorageNodeReal(groupName, ip, port);
+ BeanUtils.copyProperties(storageNodeReal, storageNode);
+ }
+
+ return storageNode;
+ }
+
+ /**
+ * 获取节点真实的IP,端口信息
+ * @param groupName 组名
+ * @param ip IP
+ * @param port 端口
+ * @return 真实的IP, 端口信息
+ */
+ private StorageNodeReal getStorageNodeReal(String groupName, String ip, Integer port) {
+
+ Map> ipMapping = storageNodeConfig.getIpMapping();
+
+ StorageNodeReal storageNodeReal = new StorageNodeReal();
+ storageNodeReal.setGroupName(groupName);
+ storageNodeReal.setIp(ip);
+ storageNodeReal.setPort(port);
+
+ if (MapUtils.isNotEmpty(ipMapping)) {
+ if (ipMapping.containsKey(groupName)) {
+ String host = ip + "-" + port;
+ Map realNode = ipMapping.get(groupName);
+ if (MapUtils.isNotEmpty(realNode) && realNode.containsKey(host)) {
+ String[] node = StringUtils.split(realNode.get(host), "-");
+ storageNodeReal.setIp(node[0]);
+ storageNodeReal.setPort(Integer.parseInt(node[1]));
+ }
+ }
+ }
+
+ return storageNodeReal;
+ }
+
+ private List getFields(Object obj) {
+ return Arrays.asList(obj.getClass().getDeclaredFields());
+ }
+
+ private Object getFieldValue(Object obj, String fieldName) {
+ List fieldList = getFields(obj);
+ for (Field field : fieldList) {
+ if (StringUtils.equalsIgnoreCase(field.getName(), fieldName)) {
+
+ boolean accessFlag = field.isAccessible();
+
+ try {
+ field.setAccessible(Boolean.TRUE);
+ return field.get(obj);
+ } catch (IllegalAccessException e) {
+ LOGGER.error("getFieldValue {}", e.getMessage());
+ }finally {
+ field.setAccessible(accessFlag);
+ }
+ }
+ }
+ return null;
+ }
+
+
+
}