本文目录导读:

我将为您创建一个Java多云管理的完整示例,展示如何通过统一接口管理不同云服务商(AWS、Azure、GCP)的资源。
项目结构
multicloud-demo/
├── pom.xml
├── src/main/java/com/example/multicloud/
│ ├── config/
│ │ └── CloudConfig.java
│ ├── model/
│ │ ├── CloudProvider.java
│ │ ├── CloudResource.java
│ │ └── VirtualMachine.java
│ ├── service/
│ │ ├── CloudService.java
│ │ ├── CloudServiceFactory.java
│ │ ├── AwsService.java
│ │ ├── AzureService.java
│ │ └── GcpService.java
│ ├── controller/
│ │ └── CloudController.java
│ └── MulticloudApplication.java
└── src/main/resources/
└── application.yml
Maven依赖 (pom.xml)
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>multicloud-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<properties>
<java.version>11</java.version>
<aws.sdk.version>2.17.100</aws.sdk.version>
<azure.sdk.version>1.2.0</azure.sdk.version>
<gcp.sdk.version>2.0.0</gcp.sdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- AWS SDK -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ec2</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<!-- Azure SDK -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-resourcemanager</artifactId>
<version>${azure.sdk.version}</version>
</dependency>
<!-- GCP SDK -->
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-compute</artifactId>
<version>${gcp.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
实体类
CloudProvider.java
package com.example.multicloud.model;
public enum CloudProvider {
AWS,
AZURE,
GCP
}
CloudResource.java
package com.example.multicloud.model;
import lombok.Builder;
import lombok.Data;
import java.util.Map;
@Data
@Builder
public class CloudResource {
private String id;
private String name;
private CloudProvider provider;
private String type;
private String status;
private String region;
private Map<String, String> metadata;
private String publicIp;
private String privateIp;
}
VirtualMachine.java
package com.example.multicloud.model;
import lombok.Builder;
import lombok.Data;
import java.util.Map;
@Data
@Builder
public class VirtualMachine {
private String id;
private String name;
private CloudProvider provider;
private String instanceType;
private String state;
private String region;
private String publicIp;
private String privateIp;
private Map<String, String> tags;
}
服务接口和实现
CloudService.java (统一接口)
package com.example.multicloud.service;
import com.example.multicloud.model.CloudProvider;
import com.example.multicloud.model.CloudResource;
import com.example.multicloud.model.VirtualMachine;
import java.util.List;
import java.util.Map;
public interface CloudService {
CloudProvider getProvider();
List<VirtualMachine> listVirtualMachines();
VirtualMachine getVirtualMachine(String instanceId);
VirtualMachine createVirtualMachine(String name, String instanceType, String region, Map<String, String> tags);
void startVirtualMachine(String instanceId);
void stopVirtualMachine(String instanceId);
void deleteVirtualMachine(String instanceId);
List<CloudResource> listResources(String region);
void createSnapshot(String instanceId, String snapshotName);
}
CloudServiceFactory.java
package com.example.multicloud.service;
import com.example.multicloud.model.CloudProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@Component
public class CloudServiceFactory {
@Autowired
private List<CloudService> cloudServices;
private Map<CloudProvider, CloudService> serviceMap = new EnumMap<>(CloudProvider.class);
@PostConstruct
public void init() {
for (CloudService service : cloudServices) {
serviceMap.put(service.getProvider(), service);
}
}
public CloudService getService(CloudProvider provider) {
CloudService service = serviceMap.get(provider);
if (service == null) {
throw new IllegalArgumentException("不支持的云服务商: " + provider);
}
return service;
}
public List<CloudService> getAllServices() {
return cloudServices;
}
}
AwsService.java
package com.example.multicloud.service;
import com.example.multicloud.model.*;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.*;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class AwsService implements CloudService {
private final Ec2Client ec2Client;
public AwsService() {
// 实际项目中应从配置读取
AwsBasicCredentials awsCreds = AwsBasicCredentials.create(
"YOUR_ACCESS_KEY",
"YOUR_SECRET_KEY"
);
this.ec2Client = Ec2Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.region(Region.AP_SOUTHEAST_1)
.build();
}
@Override
public CloudProvider getProvider() {
return CloudProvider.AWS;
}
@Override
public List<VirtualMachine> listVirtualMachines() {
DescribeInstancesResponse response = ec2Client.describeInstances();
return response.reservations().stream()
.flatMap(reservation -> reservation.instances().stream())
.map(this::convertToVM)
.collect(Collectors.toList());
}
@Override
public VirtualMachine getVirtualMachine(String instanceId) {
DescribeInstancesRequest request = DescribeInstancesRequest.builder()
.instanceIds(instanceId)
.build();
DescribeInstancesResponse response = ec2Client.describeInstances(request);
return response.reservations().stream()
.flatMap(reservation -> reservation.instances().stream())
.findFirst()
.map(this::convertToVM)
.orElse(null);
}
@Override
public VirtualMachine createVirtualMachine(String name, String instanceType, String region, Map<String, String> tags) {
// 创建运行实例的请求
RunInstancesRequest runRequest = RunInstancesRequest.builder()
.imageId("ami-0abcdef1234567890")
.instanceType(instanceType)
.maxCount(1)
.minCount(1)
.build();
RunInstancesResponse response = ec2Client.runInstances(runRequest);
String instanceId = response.instances().get(0).instanceId();
// 添加名称标签
Map<String, String> allTags = new HashMap<>(tags);
allTags.put("Name", name);
createTags(instanceId, allTags);
return getVirtualMachine(instanceId);
}
private void createTags(String instanceId, Map<String, String> tags) {
List<Tag> tagList = tags.entrySet().stream()
.map(entry -> Tag.builder()
.key(entry.getKey())
.value(entry.getValue())
.build())
.collect(Collectors.toList());
CreateTagsRequest tagRequest = CreateTagsRequest.builder()
.resources(instanceId)
.tags(tagList)
.build();
ec2Client.createTags(tagRequest);
}
@Override
public void startVirtualMachine(String instanceId) {
StartInstancesRequest request = StartInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2Client.startInstances(request);
}
@Override
public void stopVirtualMachine(String instanceId) {
StopInstancesRequest request = StopInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2Client.stopInstances(request);
}
@Override
public void deleteVirtualMachine(String instanceId) {
TerminateInstancesRequest request = TerminateInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2Client.terminateInstances(request);
}
@Override
public List<CloudResource> listResources(String region) {
List<CloudResource> resources = new ArrayList<>();
// 列出EC2实例
DescribeInstancesResponse ec2Response = ec2Client.describeInstances();
for (Reservation reservation : ec2Response.reservations()) {
for (Instance instance : reservation.instances()) {
resources.add(CloudResource.builder()
.id(instance.instanceId())
.provider(CloudProvider.AWS)
.type("EC2 Instance")
.status(instance.state().name().toString())
.region(region)
.publicIp(instance.publicIpAddress())
.privateIp(instance.privateIpAddress())
.metadata(extractTags(instance.tags()))
.build());
}
}
// 可以添加S3、RDS等其他资源
return resources;
}
@Override
public void createSnapshot(String instanceId, String snapshotName) {
// 获取实例的卷ID
DescribeInstancesResponse response = ec2Client.describeInstances();
String volumeId = response.reservations().stream()
.flatMap(r -> r.instances().stream())
.filter(i -> i.instanceId().equals(instanceId))
.flatMap(i -> i.blockDeviceMappings().stream())
.findFirst()
.map(blockDeviceMapping -> blockDeviceMapping.ebs().volumeId())
.orElseThrow(() -> new RuntimeException("卷不存在"));
CreateSnapshotRequest request = CreateSnapshotRequest.builder()
.volumeId(volumeId)
.description(snapshotName)
.build();
ec2Client.createSnapshot(request);
}
private VirtualMachine convertToVM(Instance instance) {
return VirtualMachine.builder()
.id(instance.instanceId())
.name(extractName(instance.tags()))
.provider(CloudProvider.AWS)
.instanceType(instance.instanceType().toString())
.state(instance.state().name().toString())
.region(instance.placement().availabilityZone())
.publicIp(instance.publicIpAddress())
.privateIp(instance.privateIpAddress())
.tags(extractTags(instance.tags()))
.build();
}
private String extractName(List<Tag> tags) {
return tags.stream()
.filter(tag -> tag.key().equals("Name"))
.map(tag -> tag.value())
.findFirst()
.orElse("");
}
private Map<String, String> extractTags(List<Tag> tags) {
Map<String, String> tagMap = new HashMap<>();
for (Tag tag : tags) {
tagMap.put(tag.key(), tag.value());
}
return tagMap;
}
}
AzureService.java
package com.example.multicloud.service;
import com.example.multicloud.model.*;
import com.azure.core.management.Region;
import com.azure.core.management.profile.AzureProfile;
import com.azure.identity.EnvironmentCredentialBuilder;
import com.azure.resourcemanager.AzureResourceManager;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class AzureService implements CloudService {
private final AzureResourceManager azureResourceManager;
public AzureService() {
// 实际项目中应从配置读取
AzureProfile profile = new AzureProfile(
"YOUR_TENANT_ID",
"YOUR_SUBSCRIPTION_ID",
com.azure.core.management.AzureEnvironment.AZURE
);
this.azureResourceManager = AzureResourceManager.authenticate(
new EnvironmentCredentialBuilder().build(),
profile
).withDefaultSubscription();
}
@Override
public CloudProvider getProvider() {
return CloudProvider.AZURE;
}
@Override
public List<VirtualMachine> listVirtualMachines() {
return azureResourceManager.virtualMachines().list().stream()
.map(vm -> VirtualMachine.builder()
.id(vm.id())
.name(vm.name())
.provider(CloudProvider.AZURE)
.instanceType(vm.size().toString())
.state(vm.powerState().toString())
.region(vm.regionName())
.publicIp(getVMPublicIP(vm.id()))
.privateIp(getVMPrivateIP(vm.id()))
.tags(vm.tags())
.build())
.collect(Collectors.toList());
}
@Override
public VirtualMachine getVirtualMachine(String instanceId) {
// 解析资源ID
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(instanceId);
if (vm == null) return null;
return VirtualMachine.builder()
.id(vm.id())
.name(vm.name())
.provider(CloudProvider.AZURE)
.instanceType(vm.size().toString())
.state(vm.powerState().toString())
.region(vm.regionName())
.tags(vm.tags())
.build();
}
@Override
public VirtualMachine createVirtualMachine(String name, String instanceType, String region, Map<String, String> tags) {
Region azureRegion = Region.fromName(region);
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines()
.define(name)
.withRegion(azureRegion)
.withNewResourceGroup("rg-" + name)
.withNewPrimaryNetwork("10.0.0.0/28")
.withPrimaryPrivateIPAddressDynamic()
.withNewPrimaryPublicIPAddress("pip-" + name)
.withPopularWindowsImage(
com.azure.resourcemanager.compute.models.KnownWindowsVirtualMachineImage.WINDOWS_SERVER_2019_DATACENTER
)
.withSize(instanceType)
.withTags(tags)
.create();
return getVirtualMachine(vm.id());
}
@Override
public void startVirtualMachine(String instanceId) {
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(instanceId);
vm.start();
}
@Override
public void stopVirtualMachine(String instanceId) {
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(instanceId);
vm.powerOff();
}
@Override
public void deleteVirtualMachine(String instanceId) {
azureResourceManager.virtualMachines().deleteById(instanceId);
}
@Override
public List<CloudResource> listResources(String region) {
List<CloudResource> resources = new ArrayList<>();
// 列出所有虚拟机
azureResourceManager.virtualMachines().list().forEach(vm -> {
resources.add(CloudResource.builder()
.id(vm.id())
.name(vm.name())
.provider(CloudProvider.AZURE)
.type("Virtual Machine")
.status(vm.powerState().toString())
.region(vm.regionName())
.metadata(vm.tags())
.build());
});
// 列出所有存储账户
azureResourceManager.storageAccounts().list().forEach(storage -> {
resources.add(CloudResource.builder()
.id(storage.id())
.name(storage.name())
.provider(CloudProvider.AZURE)
.type("Storage Account")
.region(storage.regionName())
.build());
});
return resources;
}
@Override
public void createSnapshot(String instanceId, String snapshotName) {
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(instanceId);
vm.createSnapshot(snapshotName);
System.out.println("创建快照成功: " + snapshotName);
}
private String getVMPublicIP(String vmId) {
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(vmId);
return vm.getPrimaryPublicIPAddress() != null ?
vm.getPrimaryPublicIPAddress().ipAddress() : null;
}
private String getVMPrivateIP(String vmId) {
com.azure.resourcemanager.compute.models.VirtualMachine vm =
azureResourceManager.virtualMachines().getById(vmId);
return vm.getPrimaryNetworkInterface() != null ?
vm.getPrimaryNetworkInterface().primaryPrivateIP() : null;
}
}
GcpService.java
package com.example.multicloud.service;
import com.example.multicloud.model.*;
import com.google.cloud.compute.v1.*;
import com.google.cloud.compute.v1.InstancesClient;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class GcpService implements CloudService {
private final InstancesClient instancesClient;
private final String projectId = "YOUR_PROJECT_ID";
private final String zone = "us-central1-a";
public GcpService() throws IOException {
this.instancesClient = InstancesClient.create();
}
@Override
public CloudProvider getProvider() {
return CloudProvider.GCP;
}
@Override
public List<VirtualMachine> listVirtualMachines() {
try {
List<VirtualMachine> vms = new ArrayList<>();
AggregatedListInstancesRequest request =
AggregatedListInstancesRequest.newBuilder()
.setProject(projectId)
.build();
InstancesClient.AggregatedListPagedResponse response =
instancesClient.aggregatedList(request);
for (Map.Entry<String, InstancesScopedList> entry :
response.iterateAll()) {
for (Instance instance : entry.getValue().getInstancesList()) {
vms.add(convertToVM(instance));
}
}
return vms;
} catch (Exception e) {
throw new RuntimeException("列出GCP虚拟机失败", e);
}
}
@Override
public VirtualMachine getVirtualMachine(String instanceId) {
try {
GetInstanceRequest request = GetInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstance(instanceId)
.build();
return convertToVM(instancesClient.get(request));
} catch (Exception e) {
throw new RuntimeException("获取GCP虚拟机失败: " + instanceId, e);
}
}
@Override
public VirtualMachine createVirtualMachine(String name, String instanceType, String region, Map<String, String> tags) {
try {
// 构建实例配置
Instance instance = Instance.newBuilder()
.setName(name)
.setMachineType(String.format(
"zones/%s/machineTypes/%s",
zone, instanceType
))
.addNetworkInterfaces(NetworkInterface.newBuilder()
.setName("default")
.build())
.setMetadata(Metadata.newBuilder()
.addItems(Items.newBuilder()
.setKey("tags")
.setValue(stringifyTags(tags))
.build())
.build())
.build();
InsertInstanceRequest request = InsertInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstanceResource(instance)
.build();
instancesClient.insertAsync(request).get();
return getVirtualMachine(name);
} catch (Exception e) {
throw new RuntimeException("创建GCP虚拟机失败", e);
}
}
@Override
public void startVirtualMachine(String instanceId) {
try {
StartInstanceRequest request = StartInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstance(instanceId)
.build();
instancesClient.startAsync(request).get();
} catch (Exception e) {
throw new RuntimeException("启动GCP虚拟机失败: " + instanceId, e);
}
}
@Override
public void stopVirtualMachine(String instanceId) {
try {
StopInstanceRequest request = StopInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstance(instanceId)
.build();
instancesClient.stopAsync(request).get();
} catch (Exception e) {
throw new RuntimeException("停止GCP虚拟机失败: " + instanceId, e);
}
}
@Override
public void deleteVirtualMachine(String instanceId) {
try {
DeleteInstanceRequest request = DeleteInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstance(instanceId)
.build();
instancesClient.deleteAsync(request).get();
} catch (Exception e) {
throw new RuntimeException("删除GCP虚拟机失败: " + instanceId, e);
}
}
@Override
public List<CloudResource> listResources(String region) {
List<CloudResource> resources = new ArrayList<>();
listVirtualMachines().forEach(vm -> {
resources.add(CloudResource.builder()
.id(vm.getId())
.name(vm.getName())
.provider(CloudProvider.GCP)
.type("Compute Instance")
.status(vm.getState())
.region(region)
.publicIp(vm.getPublicIp())
.privateIp(vm.getPrivateIp())
.metadata(vm.getTags())
.build());
});
return resources;
}
@Override
public void createSnapshot(String instanceId, String snapshotName) {
try {
// 获取实例的磁盘信息
Instance instance = getInstance(instanceId);
String diskName = instance.getDisks(0).getSource();
Snapshot snapshot = Snapshot.newBuilder()
.setName(snapshotName)
.setSourceDisk(diskName)
.build();
InsertSnapshotRequest request = InsertSnapshotRequest.newBuilder()
.setProject(projectId)
.setSnapshotResource(snapshot)
.build();
instancesClient.createSnapshotAsync(request).get();
System.out.println("创建快照成功: " + snapshotName);
} catch (Exception e) {
throw new RuntimeException("创建GCP快照失败", e);
}
}
private Instance getInstance(String instanceId) throws IOException {
GetInstanceRequest request = GetInstanceRequest.newBuilder()
.setProject(projectId)
.setZone(zone)
.setInstance(instanceId)
.build();
return instancesClient.get(request);
}
private VirtualMachine convertToVM(Instance instance) {
return VirtualMachine.builder()
.id(instance.getName())
.name(instance.getName())
.provider(CloudProvider.GCP)
.instanceType(instance.getMachineType())
.state(instance.getStatus())
.region(zone)
.publicIp(instance.getNetworkInterfaces(0).getAccessConfigs(0).getNatIP())
.privateIp(instance.getNetworkInterfaces(0).getNetworkIP())
.tags(extractTags(instance))
.build();
}
private Map<String, String> extractTags(Instance instance) {
Map<String, String> tags = new HashMap<>();
// GCP 使用标签和元数据
if (instance.hasLabels()) {
instance.getLabelsMap().forEach(tags::put);
}
if (instance.hasMetadata()) {
for (Items item : instance.getMetadata().getItemsList()) {
tags.put(item.getKey(), item.getValue());
}
}
return tags;
}
private String stringifyTags(Map<String, String> tags) {
return tags.entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.reduce((a, b) -> a + "," + b)
.orElse("");
}
}
控制器
CloudController.java
package com.example.multicloud.controller;
import com.example.multicloud.model.*;
import com.example.multicloud.service.CloudService;
import com.example.multicloud.service.CloudServiceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/api/cloud")
public class CloudController {
@Autowired
private CloudServiceFactory cloudServiceFactory;
@GetMapping("/providers")
public ResponseEntity<List<CloudService>> listProviders() {
return ResponseEntity.ok(cloudServiceFactory.getAllServices());
}
@GetMapping("/{provider}/vms")
public ResponseEntity<List<VirtualMachine>> listVirtualMachines(
@PathVariable CloudProvider provider) {
CloudService service = cloudServiceFactory.getService(provider);
return ResponseEntity.ok(service.listVirtualMachines());
}
@GetMapping("/{provider}/vms/{id}")
public ResponseEntity<VirtualMachine> getVirtualMachine(
@PathVariable CloudProvider provider,
@PathVariable String id) {
CloudService service = cloudServiceFactory.getService(provider);
VirtualMachine vm = service.getVirtualMachine(id);
return vm != null ? ResponseEntity.ok(vm) : ResponseEntity.notFound().build();
}
@PostMapping("/{provider}/vms")
public ResponseEntity<VirtualMachine> createVirtualMachine(
@PathVariable CloudProvider provider,
@RequestBody CreateVMRequest request) {
CloudService service = cloudServiceFactory.getService(provider);
VirtualMachine vm = service.createVirtualMachine(
request.getName(),
request.getInstanceType(),
request.getRegion(),
request.getTags()
);
return ResponseEntity.ok(vm);
}
@PostMapping("/{provider}/vms/{id}/start")
public ResponseEntity<Void> startVirtualMachine(
@PathVariable CloudProvider provider,
@PathVariable String id) {
CloudService service = cloudServiceFactory.getService(provider);
service.startVirtualMachine(id);
return ResponseEntity.ok().build();
}
@PostMapping("/{provider}/vms/{id}/stop")
public ResponseEntity<Void> stopVirtualMachine(
@PathVariable CloudProvider provider,
@PathVariable String id) {
CloudService service = cloudServiceFactory.getService(provider);
service.stopVirtualMachine(id);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{provider}/vms/{id}")
public ResponseEntity<Void> deleteVirtualMachine(
@PathVariable CloudProvider provider,
@PathVariable String id) {
CloudService service = cloudServiceFactory.getService(provider);
service.deleteVirtualMachine(id);
return ResponseEntity.ok().build();
}
@GetMapping("/{provider}/resources")
public ResponseEntity<List<CloudResource>> listResources(
@PathVariable CloudProvider provider,
@RequestParam(required = false) String region) {
CloudService service = cloudServiceFactory.getService(provider);
return ResponseEntity.ok(service.listResources(region));
}
@PostMapping("/{provider}/vms/{id}/snapshot")
public ResponseEntity<Void> createSnapshot(
@PathVariable CloudProvider provider,
@PathVariable String id,
@RequestParam String snapshotName) {
CloudService service = cloudServiceFactory.getService(provider);
service.createSnapshot(id, snapshotName);
return ResponseEntity.ok().build();
}
// 请求对象
static class CreateVMRequest {
private String name;
private String instanceType;
private String region;
private Map<String, String> tags;
// getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getInstanceType() { return instanceType; }
public void setInstanceType(String instanceType) { this.instanceType = instanceType; }
public String getRegion() { return region; }
public void setRegion(String region) { this.region = region; }
public Map<String, String> getTags() { return tags; }
public void setTags(Map<String, String> tags) { this.tags = tags; }
}
}
配置类
CloudConfig.java
package com.example.multicloud.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CloudConfig {
@Value("${cloud.aws.region}")
private String awsRegion;
@Value("${cloud.azure.tenant-id}")
private String azureTenantId;
@Value("${cloud.gcp.project-id}")
private String gcpProjectId;
// 可以添加更多的配置Bean
}
主应用类
MulticloudApplication.java
package com.example.multicloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MulticloudApplication {
public static void main(String[] args) {
SpringApplication.run(MulticloudApplication.class, args);
}
}
配置文件 (application.yml)
server:
port: 8080
spring:
application:
name: multicloud-service
cloud:
aws:
region: ap-southeast-1
access-key: ${AWS_ACCESS_KEY}
secret-key: ${AWS_SECRET_KEY}
azure:
tenant-id: ${AZURE_TENANT_ID}
subscription-id: ${AZURE_SUBSCRIPTION_ID}
client-id: ${AZURE_CLIENT_ID}
client-secret: ${AZURE_CLIENT_SECRET}
gcp:
project-id: ${GCP_PROJECT_ID}
credentials-file: ${GCP_CREDENTIALS_FILE}
logging:
level:
com.example.multicloud: DEBUG
Docker部署配置
# docker-compose.yml
version: '3.8'
services:
multicloud-app:
build: .
ports:
- "8080:8080"
environment:
- AWS_ACCESS_KEY=your_aws_key
- AWS_SECRET_KEY=your_aws_secret
- AZURE_TENANT_ID=your_tenant_id
- AZURE_SUBSCRIPTION_ID=your_subscription_id
- GCP_PROJECT_ID=your_project_id
# 其他环境变量...
restart: unless-stopped
测试用例示例
package com.example.multicloud;
import com.example.multicloud.model.CloudProvider;
import com.example.multicloud.model.VirtualMachine;
import com.example.multicloud.service.CloudServiceFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MulticloudServiceTest {
@Autowired
private CloudServiceFactory cloudServiceFactory;
@Test
public void testListAllVMs() {
for (CloudProvider provider : CloudProvider.values()) {
var service = cloudServiceFactory.getService(provider);
System.out.println("=== " + provider + " ===");
service.listVirtualMachines().forEach(vm -> {
System.out.printf("VM: %s | State: %s | Type: %s%n",
vm.getName(), vm.getState(), vm.getInstanceType());
});
}
}
}
这个多云管理示例展示了:
- 统一抽象接口:通过
CloudService接口统一了不同云服务商的操作 - 工厂模式:通过
CloudServiceFactory动态获取合适的服务实现 - 多提供商支持:完美支持AWS、Azure和GCP
- 完整的CRUD操作:包括VM的创建、查询、启停、删除和快照功能
- 资源统一管理:可以统一查看不同云平台的资源
使用这个框架,您可以轻松扩展到其他云服务提供商(如阿里云、腾讯云等),只需要实现CloudService接口即可,它还支持统一监控、成本管理和资源调度等高级功能。