listBucketList(OssConfig ossConfig);
+
+
+ /**
+ * Lists up to 1000 objects in the specified bucket.
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Bucket/ListObjects
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @return
+ */
+ ObjectListing listBucketObjects(OssConfig ossConfig, String bucketName);
+
+ /**
+ * Checks to see if a bucket exists and that the requester has permission to access it.
+ *
+ * @param ossConfig
+ * @param bucketName
+ */
+ void headBucket(OssConfig ossConfig, String bucketName);
+
+
+ /**
+ * Creates a new bucket.
+ *
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Bucket/PutBucket
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @return
+ */
+ Bucket createBucket(OssConfig ossConfig, String bucketName);
+
+
+ /**
+ * Deletes a bucket. All objects in the bucket must be deleted before the bucket itself can be deleted.
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Bucket/DeleteBucket
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @return
+ */
+ boolean deleteBucket(OssConfig ossConfig, String bucketName);
+
+ /**
+ * Get the location of bucket's region.
+ *
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Bucket/GetLocation
+ *
+ * @param ossConfig
+ * @param bucketName
+ */
+ void getBucketLocation(OssConfig ossConfig, String bucketName);
+
+
+
+ /* *
+ * 对象操作
* */
- void listBucketList();
- void deleteBucket();
+ /**
+ * Retrieves an object.
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/GetObject
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @param objectName
+ * @return
+ */
+ S3Object getObject(OssConfig ossConfig, String bucketName, String objectName);
+
+ /**
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/DeleteObject
+ * Deletes an object.
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @param objectName
+ * @return
+ */
+ boolean deleteObject(OssConfig ossConfig, String bucketName, String objectName);
+
+ /**
+ * Gets the user-defined metadata and entity tag for an object.
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/HeadObject
+ *
+ * @param ossConfig
+ * @param objectName
+ * @return
+ */
+ ObjectMetadata headObject(OssConfig ossConfig, String bucketName, String objectName);
+
+
+ /**
+ * Creates a new object or overwrites an existing one.
+ *
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/PutObject
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @param objectName
+ * @return
+ */
+ ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, MultipartFile file);
+
+ /**
+ * Creates a new object or overwrites an existing one.
+ *
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/PutObject
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @param objectName
+ * @return
+ */
+ ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, File file);
+
+
+ /**
+ * Restores the object as defined in the request body.
+ * https://docs.oracle.com/en-us/iaas/api/#/en/s3objectstorage/20160918/Object/RestoreObjects
+ *
+ * @param ossConfig
+ * @param bucketName
+ * @param objectName
+ * @return
+ */
+ String restoreObject(OssConfig ossConfig, String bucketName, String objectName);
+
+
}
diff --git a/server/src/main/java/io/wdd/func/oss/service/OSSCoreServiceImpl.java b/server/src/main/java/io/wdd/func/oss/service/OSSCoreServiceImpl.java
index 4cf14c6..4f73777 100644
--- a/server/src/main/java/io/wdd/func/oss/service/OSSCoreServiceImpl.java
+++ b/server/src/main/java/io/wdd/func/oss/service/OSSCoreServiceImpl.java
@@ -1,18 +1,20 @@
package io.wdd.func.oss.service;
-import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
+import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
-import com.amazonaws.services.s3.model.Bucket;
-import io.wdd.func.oss.config.OSSConfiguration;
+import com.amazonaws.services.s3.model.*;
+import io.wdd.func.oss.config.OssConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
-import org.yaml.snakeyaml.Yaml;
+import org.springframework.web.multipart.MultipartFile;
-import javax.annotation.Resource;
-import java.util.LinkedHashMap;
+import java.io.File;
+import java.io.IOException;
import java.util.List;
-import java.util.Map;
+import java.util.stream.Collectors;
+
+import static io.wdd.func.oss.config.OSSConfiguration.ALL_OSS_CONFIG;
/**
* https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/s3compatibleapi.htm#usingAPI
@@ -22,50 +24,185 @@ import java.util.Map;
public class OSSCoreServiceImpl implements OSSCoreService {
- @Resource
- OSSConfiguration ossConfiguration;
+ @Override
+ public List> listAllBucket() {
-
- /**
- * 使用Linstener 更新OSS的配置信息
- * @param content 获取到的更新的Nacos
- */
- @NacosConfigListener(dataId = "octopus-server-k3s.yaml", groupId = "k3s")
- public void listener(String content){
-
- System.out.println("content = " + content);
-
- Yaml yaml = new Yaml();
-
- Map contextMap = yaml.load(content);
-
- Map ossObject = (Map) contextMap.get("oss");
- LinkedHashMap> map = (LinkedHashMap>) ossObject.get("oralce");
-
- // 需要同步这些
-// synchronized (oracle) {
-//
-// oracle.clear();
-// oracle.putAll(map);
-//
-// }
-
- System.out.println("map = " + map);
+ return ALL_OSS_CONFIG
+ .stream()
+ .map(
+ ossConfig -> listBucketList(ossConfig)
+ )
+ .collect(Collectors.toList());
}
@Override
- public void listBucketList() {
+ public List listBucketList(OssConfig ossConfig) {
+ AmazonS3 client = ossConfig.getClient();
- AmazonS3 amazonS3 = ossConfiguration.ALL_S3_CLIENT.get(0);
-
- List buckets = amazonS3.listBuckets();
-
-
- System.out.println("buckets = " + buckets);
+ return client.listBuckets();
}
@Override
- public void deleteBucket() {
+ public ObjectListing listBucketObjects(OssConfig ossConfig, String bucketName) {
+ AmazonS3 client = ossConfig.getClient();
+
+ return client.listObjects(bucketName);
+ }
+
+ @Override
+ public void headBucket(OssConfig ossConfig, String bucketName) {
+ AmazonS3 client = ossConfig.getClient();
+
+
+ HeadBucketResult headBucketResult = client.headBucket(
+ new HeadBucketRequest(bucketName)
+ );
+
+
+ }
+
+ @Override
+ public Bucket createBucket(OssConfig ossConfig, String bucketName) {
+ AmazonS3 client = ossConfig.getClient();
+
+ Bucket bucket = client.createBucket(
+ bucketName
+ );
+
+
+ return bucket;
+ }
+
+ @Override
+ public boolean deleteBucket(OssConfig ossConfig, String bucketName) {
+
+ AmazonS3 client = ossConfig.getClient();
+
+ try {
+ client.deleteBucket(bucketName);
+
+ } catch (Exception e) {
+ log.error(
+ "删除桶错误 ! ossConfig is {}, bucketName is {}",
+ ossConfig,
+ bucketName
+ );
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void getBucketLocation(OssConfig ossConfig, String bucketName) {
+
+ }
+
+ @Override
+ public S3Object getObject(OssConfig ossConfig, String bucketName, String objectName) {
+
+ AmazonS3 client = ossConfig.getClient();
+
+ return client.getObject(
+ bucketName,
+ objectName
+ );
+ }
+
+ @Override
+ public boolean deleteObject(OssConfig ossConfig, String bucketName, String objectName) {
+ AmazonS3 client = ossConfig.getClient();
+
+ try {
+ client.deleteObject(
+ bucketName,
+ objectName
+ );
+ } catch (SdkClientException e) {
+ log.error(
+ "删除对象错误 ! ossConfig is {}, bucketName is {}, objectName is {}",
+ ossConfig,
+ bucketName,
+ objectName
+ );
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public ObjectMetadata headObject(OssConfig ossConfig, String bucketName, String objectName) {
+
+ AmazonS3 client = ossConfig.getClient();
+
+
+ try {
+
+ return client.getObjectMetadata(
+ bucketName,
+ objectName
+ );
+
+ } catch (Exception e) {
+ log.error("错误原因 => {}", e.getMessage());
+
+ return null;
+ }
+
+ }
+
+ @Override
+ public ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, MultipartFile file) {
+ AmazonS3 client = ossConfig.getClient();
+
+ try {
+
+ ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentLength(file.getSize());
+
+ PutObjectResult putObjectResult = client.putObject(
+ bucketName,
+ objectName,
+ file.getInputStream(),
+ metadata
+ );
+
+ return putObjectResult.getMetadata();
+
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ObjectMetadata createObject(OssConfig ossConfig, String bucketName, String objectName, File file) {
+ AmazonS3 client = ossConfig.getClient();
+
+ PutObjectResult putObjectResult = client.putObject(
+ bucketName,
+ objectName,
+ file
+ );
+
+ return putObjectResult.getMetadata();
+ }
+
+ @Override
+ public String restoreObject(OssConfig ossConfig, String bucketName, String objectName) {
+ AmazonS3 client = ossConfig.getClient();
+
+
+ RestoreObjectResult restoreObjectResult = client.restoreObjectV2(
+ new RestoreObjectRequest(
+ bucketName,
+ objectName
+ )
+ );
+
+
+ return restoreObjectResult.getRestoreOutputPath();
}
}
diff --git a/server/src/main/java/io/wdd/func/oss/service/OssBackendSelect.java b/server/src/main/java/io/wdd/func/oss/service/OssBackendSelect.java
new file mode 100644
index 0000000..c978af1
--- /dev/null
+++ b/server/src/main/java/io/wdd/func/oss/service/OssBackendSelect.java
@@ -0,0 +1,79 @@
+package io.wdd.func.oss.service;
+
+import com.amazonaws.services.s3.AmazonS3;
+import io.wdd.func.oss.config.OssConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import static io.wdd.func.oss.config.OSSConfiguration.ALL_OSS_CONFIG;
+
+/**
+ * 对象存储后端选择
+ * 指定一系列的策略,选出最为合适的OSS存储后端位置
+ */
+@Service
+@Slf4j
+public class OssBackendSelect {
+
+ public OssConfig one(String BackendPrefixName){
+
+ if (StringUtils.isEmpty(BackendPrefixName)) {
+ return oneRandom();
+ }
+
+ List ossConfigList = all(BackendPrefixName);
+
+ if (ossConfigList.size() == 0) {
+ log.error("没能找到合适的OSS后端存储,请确保输入正确!");
+ } else if (ossConfigList.size() == 1) {
+ return ossConfigList.get(0);
+ }
+
+ // 出现了多个后端存储,需要筛选出来只有一个的情况
+ // todo 根据评分计算出来最合适的一个!
+ // 选择当前储存容量最小的一个
+
+ // 随机选择一个, 也算是一个算法吧
+ Random random = new Random();
+ int pos = random
+ .ints(0,
+ ossConfigList.size())
+ .findFirst()
+ .getAsInt();
+
+
+ return ossConfigList.get(pos);
+ }
+
+ public OssConfig oneRandom() {
+
+ Random random = new Random();
+
+ int pos = random
+ .ints(0,
+ ALL_OSS_CONFIG.size())
+ .findFirst()
+ .getAsInt();
+
+ return ALL_OSS_CONFIG.get(pos);
+ }
+
+ public List all(String BackendPrefixName){
+
+ return ALL_OSS_CONFIG
+ .stream()
+ .filter(
+ ossConfig -> ossConfig
+ .getName()
+ .startsWith(BackendPrefixName)
+ )
+ .collect(Collectors.toList());
+ }
+
+
+}
diff --git a/server/src/main/java/io/wdd/rpc/init/AcceptAgentInitInfo.java b/server/src/main/java/io/wdd/rpc/init/AcceptAgentInitInfo.java
index cf553f2..ed2460c 100644
--- a/server/src/main/java/io/wdd/rpc/init/AcceptAgentInitInfo.java
+++ b/server/src/main/java/io/wdd/rpc/init/AcceptAgentInitInfo.java
@@ -236,7 +236,8 @@ public class AcceptAgentInitInfo {
// validate serverName
String[] split = serverName.split("-");
if (split.length <= 2 || !ALL_SERVER_CITY_INFO.contains(split[0]) || !ALL_SERVER_ARCH_INFO.contains(split[1])) {
- throw new MyRuntimeException(" server name not validated !");
+ log.error("server info from agent are {}", serverInfoVO);
+ throw new MyRuntimeException("server name not validated !");
}
String machineIdPrefixSixBytes = String.valueOf(serverInfoVO.getMachineId().toCharArray(), 0, 6);
diff --git a/server/src/main/java/io/wdd/server/config/Knife4jConfig.java b/server/src/main/java/io/wdd/server/config/Knife4jConfig.java
index 0c8388d..f14cfd0 100644
--- a/server/src/main/java/io/wdd/server/config/Knife4jConfig.java
+++ b/server/src/main/java/io/wdd/server/config/Knife4jConfig.java
@@ -48,6 +48,22 @@ public class Knife4jConfig {
}
+ @Bean
+ public Docket createFuncApiRPC() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .useDefaultResponseMessages(false)
+ .apiInfo(apiInfo())
+ .groupName("Server功能业务API")
+ .select()
+ // controller包路径,配置不对的话,找不到
+ .apis(
+ RequestHandlerSelectors.basePackage("io.wdd.func.controller")
+ )
+ .paths(PathSelectors.any())
+ .build();
+
+ }
+
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Octopus Server")
diff --git a/server/src/main/resources/application-local.yml b/server/src/main/resources/application-local.yml
deleted file mode 100644
index 77c7df1..0000000
--- a/server/src/main/resources/application-local.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-spring:
- application:
- name: octopus-server
- profiles:
- active: local
- cloud:
- nacos:
- config:
- group: local
- config-retry-time: 3000
- file-extension: yaml
- max-retry: 3
- # server-addr: 43.154.83.213:21060
- # server-addr: 140.238.52.228:21060
- server-addr: https://nacos.107421.xyz:443
- timeout: 5000
- config-long-poll-timeout: 5000
- extension-configs:
- - group: local
- data-id: common-local.yaml
-
-debug: true
-logging:
- level:
- io.wdd.server:
- debug
\ No newline at end of file
diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml
deleted file mode 100644
index 7510f0f..0000000
--- a/server/src/main/resources/application.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-server:
- port: 9999
-
-octopus:
- message:
- # agent boot up default common exchange
- init_exchange: InitExchange
- # server will send message to agent using this common queue
- init_to_server: InitToServer
- # agent boot up default common exchange routing key
- init_to_server_key: InitToServerKey
- # server will receive message from agent using this common queue
- init_from_server: InitFromServer
- # agent boot up default common exchange routing key
- init_from_server_key: InitFromServerKey
- # initialization register time out (unit ms) default is 5 min
- init_ttl: "300000"
- # Octopus Exchange Name == server comunicate with agent
- octopus_exchange: OctopusExchange
- # Octopus Message To Server == all agent send info to server queue and topic
- octopus_to_server: OctopusToServer
-
-
-spring:
- rabbitmq:
- host: 127.0.0.1
- port: 35672
- username: boge
- password: boge14@Level5
- virtual-host: /wddserver
- listener:
- simple:
- retry:
- # ack failed will reentrant the Rabbit Listener
- max-attempts: 5
- enabled: true
- # retry interval unit ms
- max-interval: 5000
- initial-interval: 5000
-
-
- redis:
- host: 127.0.0.1
- port: 36379
- database: 0
- password: boge14@Level5
-
- datasource:
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://127.0.0.1:33306/wdd_server?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
- username: root
- password: boge14@Level5
- type: com.zaxxer.hikari.HikariDataSource
- hikari:
- minimum-idle: 3
- # 空闲连接存活最大时间,默认600000(10分钟)
- idle-timeout: 180000
- # 连接池最大连接数,默认是10
- maximum-pool-size: 5
- # 此属性控制从池返回的连接的默认自动提交行为,默认值:true
- auto-commit: true
- connection-test-query: SELECT 1
-
-mybatis-plus:
- type-aliases-package: io.wdd.server.beans.po
- global-config:
- db-column-underline: true
- db-config:
- # modify ethe id strategy
- id-type: assign_id
- # logic delete field globally
- logicDeleteField: isDelete
- logic-not-delete-value: 0
- logic-delete-value: 1
- banner: false
- configuration:
- # 希望知道所有的sql是怎么执行的, 配置输出日志
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
- # 数据库下划线--实体类也是下划线 需要为false
- map-underscore-to-camel-case: true
- # 一级缓存的 缓存级别默认为 session,如果要关闭一级缓存可以设置为 statement
- local-cache-scope: session
- # 是否开启二级缓存
- cache-enabled: false
- # 默认地址为 classpath*:/mapper/**/*.xml
-# mapper-locations: classpath*:/real-mappers/**/*.xml