diff --git a/JSD-9543-需求确认书V2.docx b/JSD-9543-需求确认书V2.docx new file mode 100644 index 0000000..9991a79 Binary files /dev/null and b/JSD-9543-需求确认书V2.docx differ diff --git a/README.md b/README.md index 4f7e476..1329fb3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-9543 -JSD-9543 (S3)使用ceph的存储文件系统作为文件服务器 \ No newline at end of file +JSD-9543 (S3)使用ceph的存储文件系统作为文件服务器\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/lib/aws-java-sdk-core-1.11.902.jar b/lib/aws-java-sdk-core-1.11.902.jar new file mode 100644 index 0000000..135180e Binary files /dev/null and b/lib/aws-java-sdk-core-1.11.902.jar differ diff --git a/lib/aws-java-sdk-dynamodb-1.11.902.jar b/lib/aws-java-sdk-dynamodb-1.11.902.jar new file mode 100644 index 0000000..378858b Binary files /dev/null and b/lib/aws-java-sdk-dynamodb-1.11.902.jar differ diff --git a/lib/aws-java-sdk-ec2-1.11.902.jar b/lib/aws-java-sdk-ec2-1.11.902.jar new file mode 100644 index 0000000..6197d3a Binary files /dev/null and b/lib/aws-java-sdk-ec2-1.11.902.jar differ diff --git a/lib/aws-java-sdk-kms-1.11.902.jar b/lib/aws-java-sdk-kms-1.11.902.jar new file mode 100644 index 0000000..08114cc Binary files /dev/null and b/lib/aws-java-sdk-kms-1.11.902.jar differ diff --git a/lib/aws-java-sdk-s3-1.11.902.jar b/lib/aws-java-sdk-s3-1.11.902.jar new file mode 100644 index 0000000..ac7b48a Binary files /dev/null and b/lib/aws-java-sdk-s3-1.11.902.jar differ diff --git a/lib/commons-codec-1.11.jar b/lib/commons-codec-1.11.jar new file mode 100644 index 0000000..2245120 Binary files /dev/null and b/lib/commons-codec-1.11.jar differ diff --git a/lib/commons-logging-1.1.3.jar b/lib/commons-logging-1.1.3.jar new file mode 100644 index 0000000..ab51254 Binary files /dev/null and b/lib/commons-logging-1.1.3.jar differ diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar new file mode 100644 index 0000000..4b0a020 Binary files /dev/null and b/lib/finekit-10.0.jar differ diff --git a/lib/httpclient-4.5.13.jar b/lib/httpclient-4.5.13.jar new file mode 100644 index 0000000..218ee25 Binary files /dev/null and b/lib/httpclient-4.5.13.jar differ diff --git a/lib/httpcore-4.4.13.jar b/lib/httpcore-4.4.13.jar new file mode 100644 index 0000000..163dc43 Binary files /dev/null and b/lib/httpcore-4.4.13.jar differ diff --git a/lib/ion-java-1.0.2.jar b/lib/ion-java-1.0.2.jar new file mode 100644 index 0000000..192a98e Binary files /dev/null and b/lib/ion-java-1.0.2.jar differ diff --git a/lib/jackson-annotations-2.6.0.jar b/lib/jackson-annotations-2.6.0.jar new file mode 100644 index 0000000..0a18c34 Binary files /dev/null and b/lib/jackson-annotations-2.6.0.jar differ diff --git a/lib/jackson-core-2.6.7.jar b/lib/jackson-core-2.6.7.jar new file mode 100644 index 0000000..d195e85 Binary files /dev/null and b/lib/jackson-core-2.6.7.jar differ diff --git a/lib/jackson-databind-2.6.7.3.jar b/lib/jackson-databind-2.6.7.3.jar new file mode 100644 index 0000000..ef519d3 Binary files /dev/null and b/lib/jackson-databind-2.6.7.3.jar differ diff --git a/lib/jackson-dataformat-cbor-2.6.7.jar b/lib/jackson-dataformat-cbor-2.6.7.jar new file mode 100644 index 0000000..f008744 Binary files /dev/null and b/lib/jackson-dataformat-cbor-2.6.7.jar differ diff --git a/lib/jmespath-java-1.11.902.jar b/lib/jmespath-java-1.11.902.jar new file mode 100644 index 0000000..315f8fd Binary files /dev/null and b/lib/jmespath-java-1.11.902.jar differ diff --git a/lib/joda-time-2.8.1.jar b/lib/joda-time-2.8.1.jar new file mode 100644 index 0000000..94be659 Binary files /dev/null and b/lib/joda-time-2.8.1.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..34d8396 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,28 @@ + + + com.fr.plugin.third.party.jsdjfed + + yes + 0.4 + 10.0 + 2020-01-01 + fr.open + + + + * + + + + + + + + + + + + + + diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FactoryProvider.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FactoryProvider.java new file mode 100644 index 0000000..080d219 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FactoryProvider.java @@ -0,0 +1,21 @@ +package com.fr.plugin.third.party.jsdjfed; + +import com.fr.intelli.record.Focus; +import com.fr.io.base.provider.RepositoryFactoryProvider; +import com.fr.io.fun.AbstractRepositoryFactoryProvider; +import com.fr.plugin.third.party.jsdjfed.core.S3Config; +import com.fr.plugin.third.party.jsdjfed.core.S3RepositoryFactory; +import com.fr.record.analyzer.EnableMetrics; + + +@EnableMetrics +public class S3FactoryProvider extends AbstractRepositoryFactoryProvider { + + private static final S3RepositoryFactory factory = new S3RepositoryFactory(); + + @Override + @Focus(id="com.fr.plugin.third.party.jsdjfed", text="") + public RepositoryFactoryProvider getFactory() { + return factory; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FileServerResource.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FileServerResource.java new file mode 100644 index 0000000..77791cf --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3FileServerResource.java @@ -0,0 +1,21 @@ +package com.fr.plugin.third.party.jsdjfed; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.plugin.third.party.jsdjfed.web.S3FileServerComponent; +import com.fr.web.struct.Atom; + + +public class S3FileServerResource extends AbstractWebResourceProvider { + + @Override + public Atom attach() { + return MainComponent.KEY; + } + + @Override + public Atom client() { + return S3FileServerComponent.KEY; + } + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/S3LocaleFinder.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3LocaleFinder.java new file mode 100644 index 0000000..dc17d90 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/S3LocaleFinder.java @@ -0,0 +1,11 @@ +package com.fr.plugin.third.party.jsdjfed; + +import com.fr.stable.fun.impl.AbstractLocaleFinder; + + +public class S3LocaleFinder extends AbstractLocaleFinder { + @Override + public String find() { + return "com/fr/plugin/third/party/jsdjfed/locale/s3"; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/config/DataConfigInitializeMonitor.java new file mode 100644 index 0000000..20a766c --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/config/DataConfigInitializeMonitor.java @@ -0,0 +1,20 @@ +package com.fr.plugin.third.party.jsdjfed.config; + +import com.amazonaws.SDKGlobalConfiguration; +import com.fanruan.api.log.LogKit; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + + +public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY,"true"); + LogKit.info("ceph https cert not check"); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3Config.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3Config.java new file mode 100644 index 0000000..3a188a1 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3Config.java @@ -0,0 +1,111 @@ +package com.fr.plugin.third.party.jsdjfed.core; + +import com.fr.config.Identifier; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; +import com.fr.io.config.CommonRepoConfig; +import com.fr.io.context.ResourceModuleContext; +import com.fr.io.context.info.GetConfig; +import com.fr.io.context.info.SetConfig; +import com.fr.stable.StringUtils; + +/** + * @author fr.open + * @version 10.0 + * Created by fr.open on 2020/6/15 + */ +public class S3Config extends CommonRepoConfig { + + public S3Config() { + super(S3RepositoryFactory.IDENTITY); + } + + @Identifier("endPoint") + private Conf endPoint = Holders.simple(StringUtils.EMPTY); + + @Identifier("region") + private Conf region = Holders.simple(StringUtils.EMPTY); + + @Identifier("accessKeyId") + private Conf accessKeyId = Holders.simple(StringUtils.EMPTY); + + @Identifier("accessKeySecret") + private Conf accessKeySecret = Holders.simple(StringUtils.EMPTY); + + @Identifier("bucket") + private Conf bucket = Holders.simple(StringUtils.EMPTY); + + @GetConfig("endPoint") + public String getEndPoint() { + return endPoint.get(); + } + + @SetConfig("endPoint") + public void setEndPoint(String endPoint) { + this.endPoint.set(endPoint); + } + + @GetConfig("region") + public String getRegion() { + return region.get(); + } + + @SetConfig("region") + public void setRegion(String region) { + this.region.set(region); + } + + @GetConfig("accessKeyId") + public String getAccessKeyId() { + return accessKeyId.get(); + } + + @SetConfig("accessKeyId") + public void setAccessKeyId(String accessKeyId) { + this.accessKeyId.set(accessKeyId); + } + + @GetConfig("accessKeySecret") + public String getAccessKeySecret() { + return accessKeySecret.get(); + } + + @SetConfig("accessKeySecret") + public void setAccessKeySecret(String accessKeySecret) { + this.accessKeySecret.set(accessKeySecret); + } + + @GetConfig("bucket") + public String getBucket() { + return bucket.get(); + } + + @SetConfig("bucket") + public void setBucket(String bucket) { + this.bucket.set(bucket); + } + + @Override + public void update(String key) { + super.update(key); + S3Config newConfig = ResourceModuleContext.getRepoConfig(S3RepositoryFactory.IDENTITY, key); + if (newConfig != null) { + this.setEndPoint(newConfig.getEndPoint()); + this.setRegion(newConfig.getRegion()); + this.setAccessKeyId(newConfig.getAccessKeyId()); + this.setAccessKeySecret(newConfig.getAccessKeySecret()); + this.setBucket(newConfig.getBucket()); + } + } + + @Override + public S3Config clone() throws CloneNotSupportedException { + S3Config cloned = (S3Config) super.clone(); + cloned.endPoint = (Conf) endPoint.clone(); + cloned.region = (Conf) region.clone(); + cloned.accessKeyId = (Conf) accessKeyId.clone(); + cloned.accessKeySecret = (Conf) accessKeySecret.clone(); + cloned.bucket = (Conf) bucket.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryFactory.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryFactory.java new file mode 100644 index 0000000..1cf7157 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryFactory.java @@ -0,0 +1,78 @@ +package com.fr.plugin.third.party.jsdjfed.core; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.S3Object; +import com.amazonaws.services.s3.model.S3ObjectInputStream; +import com.fanruan.api.log.LogKit; +import com.fr.io.base.provider.impl.ConfigRepositoryFactory; +import com.fr.io.context.info.RepositoryProfile; +import com.fr.io.repository.ResourceRepository; +import com.fr.stable.AssistUtils; + +import java.io.IOException; + + +public class S3RepositoryFactory extends ConfigRepositoryFactory { + + static final String IDENTITY = "ceph"; + private static final String TEST_KEY = "test_key"; + private static final String TEST_CONTENT = "test content"; + + public S3RepositoryFactory() { + super(IDENTITY); + } + + @Override + public Class> getProfileClass() { + return S3RepositoryProfile.class; + } + + @Override + public Class getConfigClass() { + return S3Config.class; + } + + @Override + public boolean verifyConfig(S3Config config) { + try { + BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret()); + AmazonS3 s3 = AmazonS3ClientBuilder.standard() + .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(config.getEndPoint(), config.getRegion())) + .withPathStyleAccessEnabled(true) + .withCredentials(new AWSStaticCredentialsProvider(credentials)).build(); + // listObjects方法存在问题,如果key中包含URL编码的内容,将会抛异常,修改为读写验证是否可用 + s3.putObject(config.getBucket(), TEST_KEY, TEST_CONTENT); + try (S3Object object = s3.getObject(config.getBucket(), TEST_KEY)) { + final String content = getContent(object); + s3.deleteObject(config.getBucket(), TEST_KEY); + return AssistUtils.equals(TEST_CONTENT, content); + } + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + return false; + } + } + + @Override + public ResourceRepository produce(String repoName, String workRoot, S3Config config) { + return new S3ResourceRepository(repoName, workRoot, config); + } + + private String getContent(S3Object object) { + final StringBuilder stringBuilder = new StringBuilder(); + try (S3ObjectInputStream objectContent = object.getObjectContent()) { + final byte[] bytes = new byte[4096]; + int i = 0; + while ((i = objectContent.read(bytes)) > -1) { + stringBuilder.append(new String(bytes, 0, i)); + } + } catch (IOException e) { + LogKit.error(e.getMessage(), e); + } + return stringBuilder.toString(); + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryProfile.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryProfile.java new file mode 100644 index 0000000..c81c159 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3RepositoryProfile.java @@ -0,0 +1,41 @@ +package com.fr.plugin.third.party.jsdjfed.core; + +import com.fr.config.Identifier; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; +import com.fr.io.context.info.RepositoryProfile; + +/** + * @author fr.open + * @version 10.0 + * Created by fr.open on 2020/6/15 + */ +public class S3RepositoryProfile extends RepositoryProfile { + + public S3RepositoryProfile() { + + } + + @Identifier("s3Config") + private Conf s3Config = Holders.obj(null, S3Config.class); + + + @Override + public S3Config getConfig() { + return s3Config.get(); + } + + @Override + public void setConfig(S3Config s3Config) { + this.s3Config.set(s3Config); + } + + + + @Override + public RepositoryProfile clone() throws CloneNotSupportedException { + S3RepositoryProfile cloned = (S3RepositoryProfile) super.clone(); + cloned.s3Config = (Conf) s3Config.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3ResourceRepository.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3ResourceRepository.java new file mode 100644 index 0000000..a25263c --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/core/S3ResourceRepository.java @@ -0,0 +1,377 @@ +package com.fr.plugin.third.party.jsdjfed.core; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.*; +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.common.util.Strings; +import com.fr.io.repository.FineFileEntry; +import com.fr.io.repository.base.BaseResourceRepository; +import com.fr.stable.ArrayUtils; +import com.fr.stable.AssistUtils; +import com.fr.stable.Filter; +import com.fr.stable.StableUtils; +import com.fr.workspace.resource.ResourceIOException; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +/** + * @author fr.open + * @version 10.0 + * Created by fr.open on 2020/6/15 + */ +public class S3ResourceRepository extends BaseResourceRepository { + + private static final String DELIMITER = "/"; + + private final AmazonS3 s3; + private final String bucket; + + + public S3ResourceRepository(String repoName, String workRoot, S3Config config) { + super(repoName, workRoot); + BasicAWSCredentials credentials = new BasicAWSCredentials(config.getAccessKeyId(), config.getAccessKeySecret()); + this.s3 = AmazonS3ClientBuilder.standard() + .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(config.getEndPoint(), config.getRegion())) + .withPathStyleAccessEnabled(true) + .withCredentials(new AWSStaticCredentialsProvider(credentials)).build(); + this.bucket = config.getBucket(); + } + + @Override + public String getSeparator() { + return "/"; + } + + @Override + public FineFileEntry getEntry(String path) { + GetObjectRequest request = new GetObjectRequest(bucket, path); + try { + S3Object s3Object = s3.getObject(request); + try { + return s3Object2FileEntry(s3Object, path); + } finally { + s3Object.close(); + } + } catch (Exception e) { + LogKit.info("ceph getEntry path:" + path + "," + e.getMessage()); + } + + return null; + } + + @Override + public FineFileEntry[] listEntry(String dir) { + List result = new ArrayList<>(); + if (!dir.endsWith(DELIMITER)) { + dir += DELIMITER; + } + ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucket) + .withPrefix(dir).withDelimiter(DELIMITER); + ObjectListing objectListing = s3.listObjects(listObjectsRequest); + for (S3ObjectSummary summary : objectListing.getObjectSummaries()) { + String key = summary.getKey(); + if (!key.endsWith(DELIMITER)) { + result.add(s3Object2FileEntry(summary, key)); + } + } + for (String prefix : objectListing.getCommonPrefixes()) { + FineFileEntry entry = new FineFileEntry(prefix); + entry.setDirectory(true); + result.add(entry); + } + + return result.toArray(new FineFileEntry[0]); + } + + @Override + public boolean copy(String source, String target) throws ResourceIOException { + if (AssistUtils.equals(source, target) + || Strings.isEmpty(source) + || Strings.isEmpty(target)) { + return true; + } + boolean result = true; + if (this.isDirectory(source)) { + final String[] list = list(source); + if (!ArrayUtils.isEmpty(list)) { + for (String s : list) { + String targetKey = StableUtils.pathJoin(target, s); + String sourceKey = StableUtils.pathJoin(source, s); + result = result && this.copy(sourceKey, targetKey); + } + } + } else { + try { + s3.copyObject(bucket, source, bucket, target); + return true; + } catch (Exception e) { + LogKit.error(e, "copy {} to {} failed, because : ", source, target, e.getMessage()); + return false; + } + } + return result; + } + + private FineFileEntry s3Object2FileEntry(S3ObjectSummary s3Object, String path) { + FineFileEntry entry = new FineFileEntry(path); + entry.setDirectory(s3Object.getKey().endsWith("/")); + entry.setSize(s3Object.getSize()); + entry.setTimestamp(s3Object.getLastModified().getTime()); + return entry; + } + + private FineFileEntry s3Object2FileEntry(S3Object s3Object, String path) { + FineFileEntry entry = new FineFileEntry(path); + entry.setDirectory(s3Object.getKey().endsWith("/")); + entry.setSize(s3Object.getObjectMetadata().getContentLength()); + entry.setTimestamp(s3Object.getObjectMetadata().getLastModified().getTime()); + return entry; + } + + @Override + public URL getResource(String path) { + throw new RuntimeException("Not support method."); + } + + @Override + public InputStream read(String filePath) throws ResourceIOException { + LogKit.info("ceph read path:" + filePath); + GetObjectRequest request = new GetObjectRequest(bucket, filePath); + try { + S3Object s3Object = s3.getObject(request); + return s3Object.getObjectContent(); + } catch (Exception e) { + LogKit.info("ceph read path:" + filePath + "," + e.getMessage()); + return new ByteArrayInputStream(new byte[0]); + } + } + + @Override + public void write(String path, byte[] data) { + LogKit.info("ceph write path:" + path); + ObjectMetadata metadata; + try { + metadata = s3.getObjectMetadata(bucket, path); + } catch (Exception e) { + LogKit.info("ceph write path:" + path + "," + e.getMessage()); + metadata = new ObjectMetadata(); + String mimeType = URLConnection.guessContentTypeFromName(path); + if (mimeType != null) { + metadata.setContentType(mimeType); + } + metadata.setContentLength(data.length); + } + metadata = createMetadata(metadata, path, data.length); + s3.putObject(bucket, path, new ByteArrayInputStream(data), metadata); + } + + private ObjectMetadata createMetadata(ObjectMetadata metadata, String path, long contentLength) { + if (metadata == null) { + metadata = new ObjectMetadata(); + } + String mimeType = URLConnection.guessContentTypeFromName(path); + if (StringKit.isNotEmpty(mimeType)) { + metadata.setContentType(mimeType); + } + metadata.setContentLength(contentLength); + return metadata; + } + + + @Override + public boolean createFile(String path) { + PutObjectRequest request = new PutObjectRequest(bucket, path, new ByteArrayInputStream(new byte[0]), new ObjectMetadata()); + try { + s3.putObject(request); + } catch (Exception e) { + return false; + } + return true; + } + + @Override + public boolean createDirectory(String path) { + PutObjectRequest request = new PutObjectRequest(bucket, path + "/", new ByteArrayInputStream(new byte[0]), new ObjectMetadata()); + try { + s3.putObject(request); + } catch (Exception e) { + return false; + } + return true; + } + + @Override + public boolean delete(String path) { + try { + s3.deleteObject(bucket, path); + } catch (Exception e) { + LogKit.info("ceph delete path:" + path + "," + e.getMessage()); + //LogKit.error(e.getMessage(), e); + return false; + } + return true; + } + + @Override + public boolean exist(String path) { + try { + if (path.endsWith("/reportlets")) { + path = path + "/"; + } + return s3.doesObjectExist(bucket, path); + } catch (Exception e) { + LogKit.info("ceph exist path:" + path + "," + e.getMessage()); + return false; + } + } + + @Override + public String[] list(String dir, final Filter filter) { + List result = new ArrayList<>(); + if (!dir.endsWith(DELIMITER)) { + dir += DELIMITER; + } + ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucket) + .withPrefix(dir).withDelimiter(DELIMITER); + ObjectListing objectListing = s3.listObjects(listObjectsRequest); + for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) { + String[] arr = objectSummary.getKey().split(DELIMITER); + String name = arr[arr.length - 1]; + if (filter == null) { + result.add(name); + } else { + if (filter.accept(name)) { + result.add(name); + } + } + } + for (String prefix : objectListing.getCommonPrefixes()) { + String[] arr = prefix.split(DELIMITER); + String name = arr[arr.length - 1] + DELIMITER; + if (filter == null) { + result.add(name); + } else { + if (filter.accept(name)) { + result.add(name); + } + } + } + return result.toArray(new String[0]); + } + + @Override + public boolean isDirectory(String path) { + if (path.endsWith(DELIMITER)) { + return true; + } + ObjectListing listing = s3.listObjects(bucket, path); + if (listing.getObjectSummaries().isEmpty()) { + return false; + } + if (listing.getObjectSummaries().size() > 1) { + return true; + } else { + S3ObjectSummary summary = listing.getObjectSummaries().get(0); + return !StringKit.equals(listing.getPrefix(), summary.getKey()); + } + } + + @Override + public long lastModified(String path) { + try { + S3Object s3Object = s3.getObject(bucket, path); + if (s3Object != null) { + try { + return s3Object.getObjectMetadata().getLastModified().getTime(); + } finally { + s3Object.close(); + } + } + } catch (Exception e) { + LogKit.info("ceph lastModified path:" + path + "," + e.getMessage()); + } + + return -1L; + } + + @Override + public long length(String path) { + try { + S3Object s3Object = s3.getObject(bucket, path); + if (s3Object != null) { + try { + return s3Object.getObjectMetadata().getContentLength(); + } finally { + s3Object.close(); + } + } + } catch (Exception e) { + LogKit.info("ceph length path:" + path + "," + e.getMessage()); + } + + return -1L; + } + + @Override + public boolean rename(String path, String newPath) throws ResourceIOException { + try { + CopyObjectRequest copyObjRequest = new CopyObjectRequest(bucket, + path, bucket, newPath); + s3.copyObject(copyObjRequest); + s3.deleteObject(new DeleteObjectRequest(bucket, path)); + } catch (Exception e) { + LogKit.error(e.getMessage(), e); + return false; + } + return true; + } + + @Override + public boolean copyFile(String origPath, String desPath) throws ResourceIOException { + return false; + } + + @Override + public void shutDown() { + s3.shutdown(); + } + + @Override + public String getIdentity() { + return S3RepositoryFactory.IDENTITY; + } + + + /** + * 判断路径是否文件夹 + * + * @param path + * @return + */ + private boolean isPathDirectory(String path) { + if (StringKit.isEmpty(path)) { + return false; + } + + if (path.endsWith(DELIMITER)) { + return true; + } + + int index = path.lastIndexOf(DELIMITER); + String tempPath = path.substring(index + 1); + + + return false; + } + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdjfed/web/S3FileServerComponent.java b/src/main/java/com/fr/plugin/third/party/jsdjfed/web/S3FileServerComponent.java new file mode 100644 index 0000000..a860751 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdjfed/web/S3FileServerComponent.java @@ -0,0 +1,21 @@ +package com.fr.plugin.third.party.jsdjfed.web; + +import com.fr.web.struct.Component; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; + + +public class S3FileServerComponent extends Component { + + public static S3FileServerComponent KEY = new S3FileServerComponent(); + + private S3FileServerComponent() { + + } + + @Override + public ScriptPath script(RequestClient req) { + return ScriptPath.build("com/fr/plugin/third/party/jsdjfed/web/js/bundle.js"); + } + +} diff --git a/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3.properties b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3.properties new file mode 100644 index 0000000..e45c842 --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3.properties @@ -0,0 +1,6 @@ +Plugin-S3_Input=Please Input +Plugin-S3_End_Point=Endpoint +Plugin-S3_Region=Region +Plugin-S3_Access_Key_Id=AccessKey Id +Plugin-S3_Access_Key_Secret=AccessKey Secret +Plugin-S3_Bucket=Bucket \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_en_US.properties b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_en_US.properties new file mode 100644 index 0000000..e45c842 --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_en_US.properties @@ -0,0 +1,6 @@ +Plugin-S3_Input=Please Input +Plugin-S3_End_Point=Endpoint +Plugin-S3_Region=Region +Plugin-S3_Access_Key_Id=AccessKey Id +Plugin-S3_Access_Key_Secret=AccessKey Secret +Plugin-S3_Bucket=Bucket \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_zh_CN.properties b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_zh_CN.properties new file mode 100644 index 0000000..59d0bcc --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdjfed/locale/s3_zh_CN.properties @@ -0,0 +1,6 @@ +Plugin-S3_Input=\u8BF7\u8F93\u5165 +Plugin-S3_End_Point=\u8BBF\u95EE\u57DF\u540D(Endpoint) +Plugin-S3_Region=\u5730\u57DF(Region) +Plugin-S3_Access_Key_Id=\u8BBF\u95EE\u51ED\u8BC1ID(AccessKey Id) +Plugin-S3_Access_Key_Secret=\u8BBF\u95EE\u51ED\u8BC1\u5BC6\u94A5(AccessKey Secret) +Plugin-S3_Bucket=\u5B58\u50A8\u7A7A\u95F4(Bucket) \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/third/party/jsdjfed/web/js/bundle.js b/src/main/resources/com/fr/plugin/third/party/jsdjfed/web/js/bundle.js new file mode 100644 index 0000000..e9f41b6 --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdjfed/web/js/bundle.js @@ -0,0 +1,191 @@ +BI.config("dec.constant.intelligence.cluster.file.server", function (items) { + items.push({ + value: "ceph", // 地址栏显示的hash值 + id: "decision-intelligence-cluster-file-ceph", // id + text: "ceph", // 文字 + cardType: "dec.intelligence.cluster.file.ceph" + }); + return items; +}); + + +!(function () { + var LABEL_WIDTH = 116, EDITOR_WIDTH = 300; + var S3 = BI.inherit(BI.Widget, { + + props: { + baseCls: "dec-cluster-ftp", + value: {} + }, + + _store: function () { + return BI.Models.getModel("dec.model.intelligence.cluster.file.ceph", { + value: this.options.value + }); + }, + + watch: {}, + + render: function () { + var self = this, o = this.options; + return { + type: "bi.vertical", + tgap: 15, + items: [ + { + type: "dec.label.editor.item", + textWidth: LABEL_WIDTH, + editorWidth: EDITOR_WIDTH, + watermark: BI.i18nText("Plugin-S3_Input"), + text: BI.i18nText("Plugin-S3_End_Point"), + value: this.model.endPoint, + el: { + disabled: !o.editable, + }, + ref: function (_ref) { + self.endPointRow = _ref; + }, + listeners: [{ + eventName: BI.Editor.EVENT_CHANGE, + action: function () { + self.store.setEndPoint(this.getValue()); + } + }] + }, { + type: "dec.label.editor.item", + textWidth: LABEL_WIDTH, + editorWidth: EDITOR_WIDTH, + watermark: BI.i18nText("Plugin-S3_Input"), + text: BI.i18nText("Plugin-S3_Region"), + value: this.model.region, + el: { + disabled: !o.editable, + }, + ref: function (_ref) { + self.regionRow = _ref; + }, + listeners: [{ + eventName: BI.Editor.EVENT_CHANGE, + action: function () { + self.store.setRegion(this.getValue()); + } + }] + }, { + type: "dec.label.editor.item", + textWidth: LABEL_WIDTH, + editorWidth: EDITOR_WIDTH, + watermark: BI.i18nText("Plugin-S3_Input"), + text: BI.i18nText("Plugin-S3_Access_Key_Id"), + value: this.model.accessKeyId, + el: { + disabled: !o.editable, + }, + ref: function (_ref) { + self.portRow = _ref; + }, + listeners: [{ + eventName: BI.Editor.EVENT_CHANGE, + action: function () { + self.store.setAccessKeyId(this.getValue()); + } + }] + }, + { + type: "dec.label.editor.item", + textWidth: LABEL_WIDTH, + editorWidth: EDITOR_WIDTH, + watermark: BI.i18nText("Plugin-S3_Access_Key_Secret"), + text: BI.i18nText("Plugin-S3_Access_Key_Secret"), + value: "******", + el: { + disabled: !o.editable, + }, + listeners: [{ + eventName: BI.Editor.EVENT_CHANGE, + action: function () { + self.store.setAccessKeySecret(this.getValue()); + } + }] + }, + { + type: "dec.label.editor.item", + textWidth: LABEL_WIDTH, + editorWidth: EDITOR_WIDTH, + watermark: BI.i18nText("Plugin-S3_Bucket"), + text: BI.i18nText("Plugin-S3_Bucket"), + value: this.model.bucket, + el: { + disabled: !o.editable, + }, + listeners: [{ + eventName: BI.Editor.EVENT_CHANGE, + action: function () { + self.store.setBucket(this.getValue()); + } + }] + }] + }; + }, + + getValue: function () { + return { + endPoint: this.model.endPoint, + region: this.model.region, + accessKeyId: this.model.accessKeyId, + accessKeySecret: this.model.accessKeySecret, + bucket: this.model.bucket + }; + }, + + }); + BI.shortcut("dec.intelligence.cluster.file.ceph", S3); +})(); + + +!(function () { + var Model = BI.inherit(Fix.Model, { + + state: function () { + var val = this.options.value; + return { + endPoint: val.endPoint, + region: val.region, + accessKeyId: val.accessKeyId, + accessKeySecret: val.accessKeySecret, + bucket: val.bucket + }; + }, + + computed: { + encodingArray: function () { + return BI.map(DecCst.EncodeConstants.ENCODING_ARRAY, function (i, v) { + return { + value: v + }; + }); + } + }, + + actions: { + setEndPoint: function (v) { + this.model.endPoint = v; + }, + + setRegion: function (v) { + this.model.region = v; + }, + + setAccessKeyId: function (v) { + this.model.accessKeyId = v; + }, + + setAccessKeySecret: function (v) { + this.model.accessKeySecret = v; + }, + setBucket: function (v) { + this.model.bucket = v; + } + } + }); + BI.model("dec.model.intelligence.cluster.file.ceph", Model); +})(); \ No newline at end of file