diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSAutoConfig.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSAutoConfig.java new file mode 100644 index 0000000..f4d7de2 --- /dev/null +++ b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSAutoConfig.java @@ -0,0 +1,94 @@ +package xyz.zhouxy.plusone.oss; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.List; +import java.util.Objects; + +import org.csource.common.MyException; +import org.csource.fastdfs.ClientGlobal; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import xyz.zhouxy.plusone.oss.FastDFSProperties.ConnectionPool; + +@Configuration +@EnableConfigurationProperties(FastDFSProperties.class) +@ConditionalOnClass(FastDFSUtil.class) +@EnableAutoConfiguration +public class FastDFSAutoConfig { + + @Bean + @SuppressWarnings("all") + FastDFSUtil fastDFSUtil(FastDFSProperties props) throws IOException, FastDFSException { + + List trackerServerStrList = props.getTrackerServers(); + if (CollectionUtils.isEmpty(trackerServerStrList)) { + throw new FastDFSException( + String.format("configure item %s is required - ", ClientGlobal.PROP_KEY_TRACKER_SERVERS)); + } + try { + InetSocketAddress[] trackerServers = trackerServerStrList.stream() + .map(trackerServer -> { + String[] hostPort = trackerServer.trim().split(":"); + String host = hostPort[0].trim(); + int port = Integer.parseInt(hostPort[1].trim()); + return new InetSocketAddress(host, port); + }) + .toArray(InetSocketAddress[]::new); + ClientGlobal.initByTrackers(trackerServers); + + var connectTimeoutInSecondsConf = props.getConnectTimeoutInSeconds(); + if (connectTimeoutInSecondsConf != null) { + ClientGlobal.setG_connect_timeout(connectTimeoutInSecondsConf * 1000); + } + var networkTimeoutInSecondsConf = props.getNetworkTimeoutInSeconds(); + if (networkTimeoutInSecondsConf != null) { + ClientGlobal.setG_network_timeout(networkTimeoutInSecondsConf * 1000); + } + var charsetConf = props.getCharset(); + if (StringUtils.hasText(charsetConf)) { + ClientGlobal.setG_charset(charsetConf); + } + var httpAntiStealTokenConf = props.getHttpAntiStealToken(); + if (httpAntiStealTokenConf != null) { + ClientGlobal.setG_anti_steal_token(httpAntiStealTokenConf); + } + var httpSecretKeyConf = props.getHttpSecretKey(); + if (StringUtils.hasText(httpSecretKeyConf)) { + ClientGlobal.setG_secret_key(httpSecretKeyConf); + } + var httpTrackerHttpPortConf = props.getHttpTrackerHttpPort(); + if (httpTrackerHttpPortConf != null) { + ClientGlobal.setG_tracker_http_port(httpTrackerHttpPortConf); + } + + ConnectionPool connectionPool = props.getConnectionPool(); + var poolEnabled = Objects.nonNull(connectionPool) + && Boolean.TRUE.equals(connectionPool.getEnabled()); + + if (poolEnabled) { + var poolMaxCountPerEntry = connectionPool.getMaxCountPerEntry(); + if (poolMaxCountPerEntry != null) { + ClientGlobal.g_connection_pool_max_count_per_entry = poolMaxCountPerEntry; + } + var poolMaxIdleTime = connectionPool.getMaxIdleTime(); + if (poolMaxIdleTime != null) { + ClientGlobal.g_connection_pool_max_idle_time = poolMaxIdleTime * 1000; + } + var poolMaxWaitTimeInMS = connectionPool.getMaxWaitTimeInMs(); + if (poolMaxWaitTimeInMS != null) { + ClientGlobal.g_connection_pool_max_wait_time_in_ms = poolMaxWaitTimeInMS; + } + } + return new FastDFSUtil(); + } catch (MyException e) { + throw new FastDFSException(e); + } + } +} diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSException.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSException.java index bfa367f..a34cd35 100644 --- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSException.java +++ b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSException.java @@ -1,5 +1,10 @@ package xyz.zhouxy.plusone.oss; +/** + * 封装 FastDFS 的 {@link org.csource.common.MyException} + * + * @author ZhouXY + */ public class FastDFSException extends Exception { public FastDFSException() { diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSProperties.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSProperties.java new file mode 100644 index 0000000..2d183ef --- /dev/null +++ b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSProperties.java @@ -0,0 +1,32 @@ +package xyz.zhouxy.plusone.oss; + +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@ConfigurationProperties("fastdfs") +public class FastDFSProperties { + private Integer connectTimeoutInSeconds; + private Integer networkTimeoutInSeconds; + private String charset; + private Boolean httpAntiStealToken; + private String httpSecretKey; + private Integer httpTrackerHttpPort; + private List trackerServers; + + private ConnectionPool connectionPool; + + @Getter + @Setter + public static class ConnectionPool { + private Boolean enabled; + private Integer maxCountPerEntry; + private Integer maxIdleTime; + private Integer maxWaitTimeInMs; + } +} diff --git a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSUtil.java b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSUtil.java index 542b93b..cbfc351 100644 --- a/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSUtil.java +++ b/plusone-basic/plusone-basic-infrastructure/src/main/java/xyz/zhouxy/plusone/oss/FastDFSUtil.java @@ -6,7 +6,6 @@ import java.io.InputStream; import org.csource.common.MyException; import org.csource.common.NameValuePair; -import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.FileInfo; import org.csource.fastdfs.StorageClient; import org.csource.fastdfs.StorageServer; @@ -14,38 +13,20 @@ import org.csource.fastdfs.TrackerClient; import org.csource.fastdfs.TrackerServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.core.io.ClassPathResource; import lombok.Getter; public class FastDFSUtil { - private static TrackerClient trackerClient; - private static TrackerServer trackerServer; - private static StorageServer storageServer; + private final TrackerServer trackerServer; + private final StorageServer storageServer; private static final Logger logger = LoggerFactory.getLogger(FastDFSUtil.class); - private FastDFSUtil() { - throw new IllegalStateException("Utility class"); - } - - static { - try { - String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath(); - ClientGlobal.init(filePath); - /* - * TODO【重构】 将配置信息集成在 SpringBoot 配置文件中,使用加载 Properties 对象的方式进行配置,去除 fdfs_client.conf - * Properties props = new Properties(); - * props.put(ClientGlobal.PROP_KEY_TRACKER_SERVERS, "10.0.11.101:22122,10.0.11.102:22122"); - * ClientGlobal.initByProperties(props); - */ - trackerClient = new TrackerClient(); - trackerServer = trackerClient.getTrackerServer(); - storageServer = trackerClient.getStoreStorage(trackerServer); - } catch (Exception e) { - logger.error("FastDFS Client Init Fail!", e); - } + FastDFSUtil() throws IOException, MyException { + TrackerClient trackerClient = new TrackerClient(); + this.trackerServer = trackerClient.getTrackerServer(); + this.storageServer = trackerClient.getStoreStorage(trackerServer); } /** @@ -62,7 +43,7 @@ public class FastDFSUtil { * return null if fail * @throws FastDFSException */ - public static String[] upload(FastDFSFile file) throws FastDFSException { + public String[] upload(FastDFSFile file) throws FastDFSException { logger.info("File Name: {}, File Length: {}", file.getName(), file.getContent().length); NameValuePair[] metaList = new NameValuePair[1]; @@ -72,7 +53,7 @@ public class FastDFSUtil { StorageClient storageClient = null; String[] uploadResults = null; try { - storageClient = new StorageClient(trackerServer, storageServer); + storageClient = new StorageClient(this.trackerServer, this.storageServer); uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), metaList); if (uploadResults == null) { @@ -90,9 +71,9 @@ public class FastDFSUtil { return uploadResults; } - public static FileInfo getFile(String groupName, String remoteFileName) throws FastDFSException { + public FileInfo getFile(String groupName, String remoteFileName) throws FastDFSException { try { - StorageClient storageClient = new StorageClient(trackerServer, storageServer); + StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer); return storageClient.get_file_info(groupName, remoteFileName); } catch (IOException e) { throw new FastDFSException("IO Exception: Get File from Fast DFS failed", e); @@ -101,9 +82,9 @@ public class FastDFSUtil { } } - public static InputStream downFile(String groupName, String remoteFileName) throws FastDFSException { + public InputStream downFile(String groupName, String remoteFileName) throws FastDFSException { try { - StorageClient storageClient = new StorageClient(trackerServer, storageServer); + StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer); byte[] fileByte = storageClient.download_file(groupName, remoteFileName); InputStream ins = new ByteArrayInputStream(fileByte); return ins; @@ -114,8 +95,8 @@ public class FastDFSUtil { } } - public static void deleteFile(String groupName, String remoteFileName) throws FastDFSException { - StorageClient storageClient = new StorageClient(trackerServer, storageServer); + public void deleteFile(String groupName, String remoteFileName) throws FastDFSException { + StorageClient storageClient = new StorageClient(this.trackerServer, this.storageServer); try { int i = storageClient.delete_file(groupName, remoteFileName); if (i == 0) { diff --git a/plusone-start/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/plusone-start/src/main/resources/META-INF/additional-spring-configuration-metadata.json index d65dd7f..1fc399c 100644 --- a/plusone-start/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/plusone-start/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,34 +1,57 @@ -{ - "properties": [ - { - "name": "plusone.application.name", - "type": "java.lang.String", - "description": "A description for 'plusone.application.name'" - }, - { - "name": "plusone.server.port", - "type": "java.lang.Integer", - "description": "A description for 'plusone.server.port'" - }, - { - "name": "plusone.debug", - "type": "java.lang.Boolean", - "description": "A description for 'plusone.debug'" - }, - { - "name": "plusone.mail.host", - "type": "java.lang.String", - "description": "A description for 'plusone.mail.host'" - }, - { - "name": "plusone.mail.password", - "type": "java.lang.String", - "description": "A description for 'plusone.mail.password'" - }, - { - "name": "plusone.exception.handle-all-exception", - "type": "java.lang.Boolean", - "description": "A description for 'plusone.exception.handle-all-exception'" - } - ] -} +{"properties": [ + { + "name": "plusone.application.name", + "type": "java.lang.String", + "description": "A description for 'plusone.application.name'" + }, + { + "name": "plusone.server.port", + "type": "java.lang.Integer", + "description": "A description for 'plusone.server.port'" + }, + { + "name": "plusone.debug", + "type": "java.lang.Boolean", + "description": "A description for 'plusone.debug'" + }, + { + "name": "plusone.mail.host", + "type": "java.lang.String", + "description": "A description for 'plusone.mail.host'" + }, + { + "name": "plusone.mail.password", + "type": "java.lang.String", + "description": "A description for 'plusone.mail.password'" + }, + { + "name": "plusone.exception.handle-all-exception", + "type": "java.lang.Boolean", + "description": "A description for 'plusone.exception.handle-all-exception'" + }, + { + "name": "fastdfs.http_anti_steal_token", + "type": "java.lang.String", + "description": "A description for 'fastdfs.http_anti_steal_token'" + }, + { + "name": "fastdfs.http_secret_key", + "type": "java.lang.String", + "description": "A description for 'fastdfs.http_secret_key'" + }, + { + "name": "fastdfs.http_tracker_http_port", + "type": "java.lang.String", + "description": "A description for 'fastdfs.http_tracker_http_port'" + }, + { + "name": "fastdfs.network_timeout_in_seconds", + "type": "java.lang.String", + "description": "A description for 'fastdfs.network_timeout_in_seconds'" + }, + { + "name": "fastdfs.tracker_servers", + "type": "java.util.List", + "description": "A description for 'fastdfs.tracker_servers'" + } +]} diff --git a/plusone-start/src/main/resources/application-public.yaml b/plusone-start/src/main/resources/application-public.yaml index d9a2af1..2c4e7c0 100644 --- a/plusone-start/src/main/resources/application-public.yaml +++ b/plusone-start/src/main/resources/application-public.yaml @@ -62,3 +62,17 @@ plusone: # 异常拦截机制是否拦截所有异常 exception: handle-all-exception: false + +fastdfs: + connect_timeout_in_seconds: 5 + network_timeout_in_seconds: 30 + charset: UTF-8 + http_anti_steal_token: false + http_secret_key: FastDFS1234567890 + http_tracker_http_port: 80 + tracker_servers: 10.0.11.201:22122,10.0.11.202:22122,10.0.11.203:22122 + connection_pool: + enabled: true + max_count_per_entry: 500 + max_idle_time: 3600 + max_wait_time_in_ms: 1000 diff --git a/plusone-start/src/main/resources/fdfs_client.conf b/plusone-start/src/main/resources/fdfs_client.conf deleted file mode 100644 index bd1a8ec..0000000 --- a/plusone-start/src/main/resources/fdfs_client.conf +++ /dev/null @@ -1,8 +0,0 @@ -connect_timeout = 60 -network_timeout = 60 -charset = UTF-8 -http.tracker_http_port = 8080 -http.anti_steal_token = no -http.secret_key = 123456 - -tracker_server = 10.30.80.199:22122 diff --git a/plusone-start/src/test/java/xyz/zhouxy/plusone/FastDFSTests.java b/plusone-start/src/test/java/xyz/zhouxy/plusone/FastDFSTests.java new file mode 100644 index 0000000..69efb0d --- /dev/null +++ b/plusone-start/src/test/java/xyz/zhouxy/plusone/FastDFSTests.java @@ -0,0 +1,33 @@ +package xyz.zhouxy.plusone; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +import javax.annotation.Resource; + +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import lombok.extern.slf4j.Slf4j; +import xyz.zhouxy.plusone.oss.FastDFSException; +import xyz.zhouxy.plusone.oss.FastDFSUtil; +import xyz.zhouxy.plusone.oss.FastDFSUtil.FastDFSFile; + +@SpringBootTest(classes = PlusoneApplication.class) +@Slf4j +class FastDFSTests { + + @Resource + FastDFSUtil fastDFSUtil; + + @Test + void testOSS() throws FileNotFoundException, IOException, FastDFSException { + try (FileInputStream in = new FileInputStream("D:\\ZhouXY\\Desktop\\666.png");) { + byte[] content = IOUtils.toByteArray(in); + String[] upload = fastDFSUtil.upload(new FastDFSFile("666.png", content, "png")); + log.info(String.join("/", upload)); + } + } +}