Skip to content

Commit 77dc7dd

Browse files
authored
Merge pull request #57 from alipay/20201030-multiAccountResouce
20201030 multi account resouce
2 parents 7a89431 + dbe603a commit 77dc7dd

File tree

12 files changed

+309
-23
lines changed

12 files changed

+309
-23
lines changed

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<url>https://github.com/alipay/rdf-file</url>
1212

1313
<properties>
14-
<rdf.file.core.version>2.2.7</rdf.file.core.version>
15-
<rdf.file.oss.version>2.2.7</rdf.file.oss.version>
16-
<rdf.file.sftp.version>2.2.7</rdf.file.sftp.version>
14+
<rdf.file.core.version>2.2.8</rdf.file.core.version>
15+
<rdf.file.oss.version>2.2.8</rdf.file.oss.version>
16+
<rdf.file.sftp.version>2.2.8</rdf.file.sftp.version>
1717
</properties>
1818

1919
<modules>

rdf-file-core/src/main/java/com/alipay/rdf/file/loader/ResourceLoader.java

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
import com.alipay.rdf.file.exception.RdfErrorEnum;
44
import com.alipay.rdf.file.exception.RdfFileException;
55
import com.alipay.rdf.file.init.RdfInit;
6+
import com.alipay.rdf.file.interfaces.FileStorage;
67
import com.alipay.rdf.file.model.FileDefaultConfig;
8+
import com.alipay.rdf.file.model.StorageConfig;
79
import com.alipay.rdf.file.resource.RdfInputStream;
810
import com.alipay.rdf.file.spi.RdfFileResourceSpi;
911
import com.alipay.rdf.file.util.RdfFileLogUtil;
1012
import com.alipay.rdf.file.util.RdfFileUtil;
1113

14+
import java.util.Collections;
15+
import java.util.Map;
16+
import java.util.Queue;
17+
import java.util.WeakHashMap;
18+
1219
/**
1320
* Copyright (C) 2013-2018 Ant Financial Services Group
1421
*
@@ -18,7 +25,13 @@
1825
public class ResourceLoader {
1926
private static final String DEFAULT_TYPE = "classpath";
2027

21-
private static final String SPLIT = ":";
28+
private static final String SPLIT = ":";
29+
// 扩展配置项key,同种协议可以指定不同配置
30+
private static final String RESOURCE_KEY = "resourceKey";
31+
32+
private static final Map<String, RdfFileResourceSpi> RESOURCE_CACHE = Collections.synchronizedMap(new WeakHashMap<String, RdfFileResourceSpi>());
33+
34+
private static final Object LOCK = new Object();
2235

2336
@SuppressWarnings({ "rawtypes", "unchecked" })
2437
public static RdfInputStream getInputStream(String path) {
@@ -28,6 +41,7 @@ public static RdfInputStream getInputStream(String path) {
2841
int idx = path.indexOf(SPLIT);
2942

3043
String resourceType = null;
44+
String resourceValue = RdfFileUtil.parsePathParams(path).get(RESOURCE_KEY);
3145

3246
if (idx < 0) {
3347
resourceType = DEFAULT_TYPE;
@@ -36,19 +50,45 @@ public static RdfInputStream getInputStream(String path) {
3650
path = path.substring(idx + 1);
3751
}
3852

39-
RdfFileResourceSpi rdfResource = ExtensionLoader
40-
.getExtensionLoader(RdfFileResourceSpi.class).getExtension(resourceType);
41-
42-
if (null == rdfResource) {
43-
throw new RdfFileException("rdf-file#ResourceLoader.getInputStream(path=" + path
44-
+ ") resourceType=" + resourceType + "没有对应的实现!",
45-
RdfErrorEnum.NOT_EXSIT);
53+
idx = path.indexOf(RdfFileUtil.QUESTION);
54+
if (idx > -1) {
55+
path = path.substring(idx + 1);
4656
}
4757

48-
rdfResource.resourceType(resourceType);
58+
String cacheKey = resourceType + (resourceValue == null ? RdfFileUtil.EMPTY : resourceValue);
4959

50-
if (rdfResource instanceof RdfInit) {
51-
((RdfInit) rdfResource).init(FileDefaultConfig.DEFAULT_FILE_PARAMS.get(resourceType));
60+
RdfFileResourceSpi rdfResource = RESOURCE_CACHE.get(cacheKey);
61+
62+
if (null == rdfResource) {
63+
synchronized (LOCK) {
64+
rdfResource = RESOURCE_CACHE.get(cacheKey);
65+
if (null == rdfResource) {
66+
rdfResource = ExtensionLoader.getExtensionLoader(RdfFileResourceSpi.class).getNewExtension(resourceType);
67+
68+
if (null == rdfResource) {
69+
throw new RdfFileException("rdf-file#ResourceLoader.getInputStream(path=" + path
70+
+ ") resourceType=" + resourceType + "没有对应的实现!",
71+
RdfErrorEnum.NOT_EXSIT);
72+
}
73+
74+
rdfResource.resourceType(resourceType);
75+
76+
if (rdfResource instanceof RdfInit) {
77+
Object configValue = null;
78+
if (RdfFileUtil.isNotBlank(resourceValue)) {
79+
// 指定了特殊配置
80+
configValue = FileDefaultConfig.DEFAULT_FILE_PARAMS.get(resourceValue);
81+
}
82+
if (null == configValue) {
83+
// 使用协议通用配置
84+
configValue = FileDefaultConfig.DEFAULT_FILE_PARAMS.get(resourceType);
85+
}
86+
((RdfInit) rdfResource).init(configValue);
87+
}
88+
89+
RESOURCE_CACHE.put(cacheKey, rdfResource);
90+
}
91+
}
5292
}
5393

5494
return rdfResource.getInputStream(path);

rdf-file-core/src/main/java/com/alipay/rdf/file/resource/ClasspathRdfResource.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
*/
1313
public class ClasspathRdfResource extends AbstractRdfResources {
1414

15-
/**
16-
* @see com.alipay.rdf.file.spi.RdfFileResourceSpi#getInputStream()
17-
*/
1815
@Override
1916
public RdfInputStream getInputStream(String path) {
2017
InputStream is = RdfFileUtil.getDefaultClassLoader().getResourceAsStream(path);

rdf-file-core/src/main/java/com/alipay/rdf/file/spi/RdfFileResourceSpi.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public interface RdfFileResourceSpi extends RdfInit<StorageConfig> {
1616
/**
1717
* 资源加载类型
1818
*
19-
* @param type
19+
* @param resourceType
2020
*/
2121
void resourceType(String resourceType);
2222

rdf-file-core/src/main/java/com/alipay/rdf/file/util/RdfFileUtil.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
import java.math.BigDecimal;
1414
import java.nio.channels.FileChannel;
1515
import java.util.ArrayList;
16+
import java.util.HashMap;
1617
import java.util.List;
18+
import java.util.Map;
1719

1820
/**
1921
* Copyright (C) 2013-2018 Ant Financial Services Group
@@ -24,10 +26,16 @@
2426
* @version $Id: RdfUtil.java, v 0.1 2017年8月8日 上午11:29:42 hongwei.quhw Exp $
2527
*/
2628
public class RdfFileUtil {
27-
private static final String EMPTY = "";
29+
public static final String EMPTY = "";
2830

2931
private static final int BUF_SIZE = 8192;
3032

33+
private static final String AMPERSAND = "&";
34+
35+
private static final String EQUALS = "=";
36+
37+
public static final String QUESTION = "?";
38+
3139
public static String trimNotNull(String text) {
3240
if (null == text) {
3341
return null;
@@ -787,4 +795,30 @@ public static String humanReadableByteCount(long bytes, boolean si) {
787795
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
788796
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
789797
}
798+
799+
public static Map<String, String> parsePathParams(String path) {
800+
Map<String, String> params = new HashMap<String, String>();
801+
802+
if (isBlank(path)) {
803+
return params;
804+
}
805+
806+
int idx = path.indexOf(QUESTION);
807+
if (idx < 0) {
808+
return params;
809+
}
810+
811+
path = path.substring(idx + 1);
812+
String[] pairs = path.split(AMPERSAND);
813+
for (String pair : pairs) {
814+
String[] param = split(pair, EQUALS);
815+
if (param.length == 2) {
816+
params.put(param[0], param[1]);
817+
} else {
818+
throw new RdfFileException("path=" + path + ", parseParams format error, it has not valid param pairs ", RdfErrorEnum.ILLEGAL_ARGUMENT);
819+
}
820+
}
821+
822+
return params;
823+
}
790824
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**
2+
* Alipay.com Inc.
3+
* Copyright (c) 2004-2020 All Rights Reserved.
4+
*/
5+
package com.alipay.rdf.file.loader;
6+
7+
import com.alipay.rdf.file.model.FileDefaultConfig;
8+
import com.alipay.rdf.file.model.StorageConfig;
9+
import com.alipay.rdf.file.resource.TestResource;
10+
import com.alipay.rdf.file.spi.RdfFileResourceSpi;
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
14+
import java.lang.reflect.Field;
15+
import java.util.Map;
16+
17+
import static com.alipay.rdf.file.loader.ResourceLoader.getInputStream;
18+
19+
/**
20+
* Copyright (C) 2013-2018 Ant Financial Services Group
21+
*
22+
* @author quhongwei
23+
* @version : ResourceLoaderTest.java, v 0.1 2020年11月01日 09:19 quhongwei Exp $
24+
*/
25+
public class ResourceLoaderTest {
26+
27+
@Test
28+
public void testGetInputStreamResourceKey() throws Exception{
29+
30+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("key1");
31+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("key1");
32+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("testResource");
33+
34+
Field field = ResourceLoader.class.getDeclaredField("RESOURCE_CACHE");
35+
field.setAccessible(true);
36+
37+
Map<String, RdfFileResourceSpi> resourceMap = ( Map<String, RdfFileResourceSpi>)field.get(null);
38+
39+
getInputStream("aa/bb/cc/dd.json");
40+
Assert.assertNotNull(resourceMap.get("classpath"));
41+
42+
getInputStream("classpath:aa/bb/cc/dd.json");
43+
Assert.assertNotNull(resourceMap.get("classpath"));
44+
45+
getInputStream("classpath:aa/bb/cc/dd.json?resourceKey=hzconfig");
46+
Assert.assertNotNull(resourceMap.get("classpath"));
47+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
48+
49+
getInputStream("classpath:aa/bb/cc/dd.json?resourceKey=shconfig");
50+
Assert.assertNotNull(resourceMap.get("classpath"));
51+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
52+
53+
getInputStream("classpath:aa/bb/cc/dd.json?resourceKey=shconfig&xx=dd");
54+
Assert.assertNotNull(resourceMap.get("classpath"));
55+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
56+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
57+
58+
59+
TestResource.TestInputStream testInputStream = (TestResource.TestInputStream)ResourceLoader.getInputStream("testResource:aa/bb/cc/dd.json");
60+
61+
Assert.assertNotNull(resourceMap.get("classpath"));
62+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
63+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
64+
Assert.assertNotNull(resourceMap.get("testResource"));
65+
66+
Assert.assertEquals("testResource", testInputStream.getResourceType());
67+
Assert.assertEquals("aa/bb/cc/dd.json", testInputStream.getPath());
68+
Assert.assertNull( testInputStream.getConfig());
69+
70+
FileDefaultConfig.DEFAULT_FILE_PARAMS.put("testResource", new StorageConfig("nas") {
71+
{
72+
addParam("type", "testResource");
73+
}
74+
});
75+
76+
FileDefaultConfig.DEFAULT_FILE_PARAMS.put("key1", new StorageConfig("nas") {
77+
{
78+
addParam("type", "key1");
79+
}
80+
});
81+
82+
FileDefaultConfig.DEFAULT_FILE_PARAMS.put("key2", new StorageConfig("nas") {
83+
{
84+
addParam("type", "key2");
85+
}
86+
});
87+
88+
testInputStream = (TestResource.TestInputStream)ResourceLoader.getInputStream("testResource:aa/bb/cc/dd.json?resourceKey=key1");
89+
Assert.assertNotNull(resourceMap.get("classpath"));
90+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
91+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
92+
Assert.assertNotNull(resourceMap.get("testResource"));
93+
Assert.assertNotNull(resourceMap.get("testResourcekey1"));
94+
95+
RdfFileResourceSpi pre = resourceMap.get("testResourcekey1");
96+
97+
// 重复看看缓存
98+
testInputStream = (TestResource.TestInputStream)ResourceLoader.getInputStream("testResource:aa/bb/cc/dd.json?resourceKey=key1");
99+
Assert.assertNotNull(resourceMap.get("classpath"));
100+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
101+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
102+
Assert.assertNotNull(resourceMap.get("testResource"));
103+
Assert.assertNotNull(resourceMap.get("testResourcekey1"));
104+
Assert.assertEquals("key1", testInputStream.getConfig().getParam("type"));
105+
Assert.assertEquals(pre, resourceMap.get("testResourcekey1"));
106+
107+
testInputStream = (TestResource.TestInputStream)ResourceLoader.getInputStream("testResource:aa/bb/cc/dd.json?resourceKey=key2");
108+
Assert.assertNotNull(resourceMap.get("classpath"));
109+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
110+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
111+
Assert.assertNotNull(resourceMap.get("testResource"));
112+
Assert.assertNotNull(resourceMap.get("testResourcekey1"));
113+
Assert.assertNotNull(resourceMap.get("testResourcekey2"));
114+
Assert.assertEquals("key2", testInputStream.getConfig().getParam("type"));
115+
116+
testInputStream = (TestResource.TestInputStream)ResourceLoader.getInputStream("testResource:aa/bb/cc/dd.json?resourceKey=key3");
117+
Assert.assertNotNull(resourceMap.get("classpath"));
118+
Assert.assertNotNull(resourceMap.get("classpathhzconfig"));
119+
Assert.assertNotNull(resourceMap.get("classpathshconfig"));
120+
Assert.assertNotNull(resourceMap.get("testResource"));
121+
Assert.assertNotNull(resourceMap.get("testResourcekey1"));
122+
Assert.assertNotNull(resourceMap.get("testResourcekey2"));
123+
Assert.assertNotNull(resourceMap.get("testResourcekey3"));
124+
Assert.assertEquals("testResource", testInputStream.getConfig().getParam("type"));
125+
126+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("key1");
127+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("key2");
128+
FileDefaultConfig.DEFAULT_FILE_PARAMS.remove("testResource");
129+
130+
}
131+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Alipay.com Inc.
3+
* Copyright (c) 2004-2020 All Rights Reserved.
4+
*/
5+
package com.alipay.rdf.file.resource;
6+
7+
import com.alipay.rdf.file.model.StorageConfig;
8+
import com.alipay.rdf.file.spi.RdfFileResourceSpi;
9+
10+
import java.io.IOException;
11+
import java.io.InputStream;
12+
13+
/**
14+
* Copyright (C) 2013-2018 Ant Financial Services Group
15+
*
16+
* @author quhongwei
17+
* @version : TestResource.java, v 0.1 2020年11月01日 09:48 quhongwei Exp $
18+
*/
19+
public class TestResource extends AbstractRdfResources {
20+
@Override
21+
public RdfInputStream getInputStream(String path) {
22+
return new TestInputStream(storageConfig, resourceType, path);
23+
}
24+
25+
public static class TestInputStream extends RdfInputStream {
26+
private final StorageConfig config;
27+
private final String resourceType;
28+
private final String path;
29+
30+
public TestInputStream(StorageConfig config, String resourceType, String path) {
31+
super(new InputStream() {
32+
@Override
33+
public int read() throws IOException {
34+
return 0;
35+
}
36+
});
37+
this.config = config;
38+
this.resourceType = resourceType;
39+
this.path = path;
40+
}
41+
42+
public StorageConfig getConfig() {
43+
return config;
44+
}
45+
46+
public String getResourceType() {
47+
return resourceType;
48+
}
49+
50+
public String getPath() {
51+
return path;
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)