martin 3 年 前
コミット
e5abbd1674

+ 11 - 0
api-common/pom.xml

@@ -17,6 +17,17 @@
     </properties>
 
     <dependencies>
+
+        <!-- minio - 开始 -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+        </dependency>
+        <!-- minio - 结束 -->
         <!-- http 客户端 -->
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>

+ 98 - 0
api-common/src/main/java/api/common/util/MinioUtil.java

@@ -0,0 +1,98 @@
+package api.common.util;
+
+import io.minio.*;
+import io.minio.errors.ErrorResponseException;
+import io.minio.errors.InsufficientDataException;
+import io.minio.errors.InvalidResponseException;
+import io.minio.errors.XmlParserException;
+import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+public class MinioUtil {
+
+    /**
+     * 判断 bucket 是否存在
+     */
+    public static boolean isBucketExist(MinioClient minioClient, String bucketName) throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
+    }
+
+    /**
+     * 创建 bucket
+     */
+    public static void createBucket(MinioClient minioClient, String bucketName) throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        if (!isBucketExist(minioClient, bucketName)) {
+            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
+        }
+    }
+
+    /**
+     * 通过文件路径上传文件上传文件
+     */
+    public static void uploadByFilePath(
+            MinioClient minioClient,
+            String sourceFilePath,
+            String bucketName,
+            String objectName
+    ) throws IOException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        minioClient.uploadObject(UploadObjectArgs.builder()
+                .filename(sourceFilePath)
+                .bucket(bucketName)
+                .object(objectName)
+                .build());
+    }
+
+    /**
+     * 通过文件路径上传文件上传文件
+     *
+     * @param partSize 分片最小 5MB
+     */
+    public static void uploadByStream(
+            MinioClient minioClient,
+            InputStream inputStream,
+            long objectSize,
+            long partSize,
+            String bucketName,
+            String objectName
+    ) throws IOException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        minioClient.putObject(PutObjectArgs.builder()
+                .stream(inputStream, objectSize, partSize)
+                .bucket(bucketName)
+                .object(objectName)
+                .build());
+    }
+
+    /**
+     * 下载文件
+     */
+    public static void downloadToFile(
+            MinioClient minioClient,
+            String bucketName,
+            String objectName,
+            String targetFilePath
+    ) throws IOException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        minioClient.downloadObject(DownloadObjectArgs.builder()
+                .bucket(bucketName)
+                .object(objectName)
+                .filename(targetFilePath)
+                .build());
+    }
+
+    /**
+     * 下载文件
+     */
+    public static InputStream downloadToStream(
+            MinioClient minioClient,
+            String bucketName,
+            String objectName
+    ) throws IOException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, io.minio.errors.ServerException, io.minio.errors.InternalException {
+        return minioClient.getObject(GetObjectArgs.builder()
+                .bucket(bucketName)
+                .object(objectName)
+                .build());
+    }
+}

+ 25 - 2
pom.xml

@@ -17,6 +17,7 @@
         <module>simulation-oauth-client</module>
         <module>simulation-resource-scheduler</module>
         <module>api-common</module>
+        <module>simulation-resource-common</module>
     </modules>
 
 
@@ -48,10 +49,13 @@
         <jjwt.version>0.9.1</jjwt.version>
         <httpclient.version>4.5.13</httpclient.version>
         <commons-pool2.version>2.11.1</commons-pool2.version>
+        <minio.version>8.3.5</minio.version>
+        <okhttp.version>4.9.3</okhttp.version>
+        <kubernetes.version>14.0.0</kubernetes.version>
     </properties>
 
 
-    <!--子模块继承之后,提供作用:锁定版本+子module不用谢groupId和version-->
+    <!--子模块继承之后,提供作用:锁定版本 +  module 不用谢 groupId  version-->
     <dependencyManagement>
         <dependencies>
 
@@ -62,6 +66,13 @@
                 <version>${logback-classic.version}</version>
             </dependency>
 
+            <!-- kubernetes 客户端 -->
+            <dependency>
+                <groupId>io.kubernetes</groupId>
+                <artifactId>client-java</artifactId>
+                <version>${kubernetes.version}</version>
+            </dependency>
+
             <!-- 缓存 - 开始 -->
             <dependency>
                 <groupId>org.apache.commons</groupId>
@@ -69,8 +80,20 @@
                 <version>${commons-pool2.version}</version>
             </dependency>
             <!-- 缓存 - 结束 -->
+            <!-- minio - 开始 -->
+            <dependency>
+                <groupId>com.squareup.okhttp3</groupId>
+                <artifactId>okhttp</artifactId>
+                <version>${okhttp.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.minio</groupId>
+                <artifactId>minio</artifactId>
+                <version>${minio.version}</version>
+            </dependency>
+            <!-- minio - 结束 -->
 
-            <!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
+            <!-- kafka -->
             <dependency>
                 <groupId>org.apache.kafka</groupId>
                 <artifactId>kafka-clients</artifactId>

+ 91 - 0
simulation-resource-common/pom.xml

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>simulation-cloud</artifactId>
+        <groupId>com.css</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>simulation-resource-common</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+
+        <!-- apache kafka - 开始 -->
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+            <version>${kafka-clients.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+        </dependency>
+        <!-- apache kafka - 结束 -->
+
+        <!-- redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- minio - 开始 -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+        </dependency>
+        <!-- minio - 结束 -->
+
+
+        <!-- nacos - 开始 -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <!-- nacos - 结束 -->
+
+        <!-- web 服务 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <!-- 参数校验 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+
+        <!-- api-common -->
+        <dependency>
+            <groupId>com.css</groupId>
+            <artifactId>api-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 14 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/SimulationResourceCommonApplication.java

@@ -0,0 +1,14 @@
+package com.css.simulation.resource.common;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SimulationResourceCommonApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(SimulationResourceCommonApplication.class, args);
+    }
+
+}

+ 35 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/configuration/kafka/producer/ApacheKafkaPartitioner.java

@@ -0,0 +1,35 @@
+package com.css.simulation.resource.common.configuration.kafka.producer;
+
+import org.apache.kafka.clients.producer.Partitioner;
+import org.apache.kafka.common.Cluster;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Map;
+
+
+/**
+ * 自定义分区器
+ */
+@Configuration
+public class ApacheKafkaPartitioner implements Partitioner {
+
+
+    /**
+     * 返回分区值。
+     */
+    @Override
+    public int partition(String s, Object o, byte[] bytes, Object o1, byte[] bytes1, Cluster cluster) {
+        // 全部发送到 0 号分区
+        return 0;
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public void configure(Map<String, ?> map) {
+
+    }
+}

+ 24 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/configuration/minio/MinioConfiguration.java

@@ -0,0 +1,24 @@
+package com.css.simulation.resource.common.configuration.minio;
+
+import io.minio.MinioClient;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "minio")
+public class MinioConfiguration {
+    private String endpoint;
+    private String accessKey;
+    private String secretKey;
+
+    @Bean
+    public MinioClient minioClient() {
+        return MinioClient.builder()
+                .endpoint(endpoint)
+                .credentials(accessKey, secretKey)
+                .build();
+    }
+}

+ 84 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/configuration/redis/RedisTemplateConfiguration.java

@@ -0,0 +1,84 @@
+package com.css.simulation.resource.common.configuration.redis;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@EnableCaching
+public class RedisTemplateConfiguration {
+
+    @Bean
+    public RedisSerializer<Object> jackson2JsonRedisSerializer() {
+        // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 redis 的 value 值。
+        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        ObjectMapper mapper = new ObjectMapper();
+        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
+        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        // 指定序列化输入的类型,类必须是非 final 修饰的,final修饰的类,比如 String, Integer 等会跑出异常
+        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+        serializer.setObjectMapper(mapper);
+        return serializer;
+    }
+
+    @Bean
+    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
+        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
+        configuration = configuration
+                // 设置 key 为 string 序列化
+                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
+                // 设置 value 为 json 序列化
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
+                // 不缓存空值
+                .disableCachingNullValues()
+                // 设置缓存默认过期时间(30 分钟)
+                .entryTtl(Duration.ofMinutes(30L))
+        ;
+        // 特殊缓存空间应用不同的配置
+        Map<String, RedisCacheConfiguration> map = new HashMap<>();
+        map.put("miFirst", configuration.entryTtl(Duration.ofMinutes(30L)));
+        map.put("miSecond", configuration.entryTtl(Duration.ofHours(1L)));
+
+        return RedisCacheManager.builder(connectionFactory)
+                .cacheDefaults(configuration)           // 默认配置
+                .withInitialCacheConfigurations(map)    // 特殊缓存
+                .transactionAware()                     // 事务
+                .build();
+    }
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(connectionFactory);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        // key 采用 String 的序列化方式
+        template.setKeySerializer(stringRedisSerializer);
+        // hash 的 key 采用 String 的序列化方式
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value 采用 jackson 的序列化方式
+        template.setValueSerializer(jackson2JsonRedisSerializer());
+        // hash 的 value 采用 jackson 的序列化方式
+        template.setHashValueSerializer(jackson2JsonRedisSerializer());
+        template.afterPropertiesSet();
+        return template;
+    }
+
+
+}

+ 7 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/controller/KafkaController.java

@@ -0,0 +1,7 @@
+package com.css.simulation.resource.common.controller;
+
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class KafkaController {
+}

+ 5 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/controller/MinioController.java

@@ -0,0 +1,5 @@
+package com.css.simulation.resource.common.controller;
+
+@RestController
+public class MinioController {
+}

+ 7 - 0
simulation-resource-common/src/main/java/com/css/simulation/resource/common/controller/RedisController.java

@@ -0,0 +1,7 @@
+package com.css.simulation.resource.common.controller;
+
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class RedisController {
+}

+ 7 - 0
simulation-resource-scheduler/pom.xml

@@ -18,6 +18,13 @@
 
     <dependencies>
 
+        <!-- kubernetes 客户端 -->
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+        </dependency>
+
+
         <!-- apache kafka - 开始 -->
         <dependency>
             <groupId>org.apache.kafka</groupId>

+ 18 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/configuration/kubernetes/KubernetesConfiguration.java

@@ -0,0 +1,18 @@
+package com.css.simulation.resource.scheduler.configuration.kubernetes;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.util.ClientBuilder;
+import io.kubernetes.client.util.KubeConfig;
+import org.springframework.context.annotation.Bean;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+public class KubernetesConfiguration {
+
+    @Bean
+    public ApiClient apiClient() throws IOException {
+        return ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader("D:\\idea-project\\kubernetes-study\\src\\main\\resources\\config"))).build();
+    }
+
+}

+ 1 - 0
simulation-resource-scheduler/src/main/java/com/css/simulation/resource/scheduler/consumer/ProjectConsumer.java

@@ -89,5 +89,6 @@ public class ProjectConsumer {
             kafkaTemplate.send(projectId, 0, taskPO.getId(), taskJson);
         }
         //4 创建 pod 开始执行。
+
     }
 }