# huaweicloud-ugo-migration-project-java **Repository Path**: HuaweiCloudDeveloper/huaweicloud-ugo-migration-project-java ## Basic Information - **Project Name**: huaweicloud-ugo-migration-project-java - **Description**: 基于数据库和应用迁移 UGO服务,创建迁移项目,将源数据库SQL转换为目标数据库兼容的SQL,迁移转换后的SQL。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master-dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-21 - **Last Updated**: 2023-11-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 0.版本说明 本示例配套的SDK版本为:3.0.104 ## 1.功能介绍 本示例展示如何基于数据库和应用迁移 UGO服务的SDK,创建迁移项目,将源数据库SQL转换为目标数据库兼容的SQL,迁移转换后的SQL。删除迁移项目后,才能删除关联的评估项目。 ## 2.前置条件 - 已[注册](https://reg.huaweicloud.com/registerui/cn/register.html?locale=zh-cn#/register)华为云, 并完成[实名认证](https://account.huaweicloud.com/usercenter/?region=cn-north-4#/accountindex/realNameAuth) 。 - 已获取华为云开发工具包(SDK)。 - 已获取华为云账号对应的Access Key(AK)和Secret Access Key(SK)。请在华为云控制台“我的凭证 > 访问密钥”页面上创建和查看您的AK/SK。 具体请参考[访问密钥](https://support.huaweicloud.com/usermanual-ca/zh-cn_topic_0046606340.html)。 - 已具备开发环境 ,支持Java JDK 1.8及其以上版本。 - 创建迁移项目至少需要一个状态为“完成”的评估项目,具体请参考“评估项目_数据库评估”示例。 - 其他前置条件请参考数据库和应用迁移 UGO服务文档的[快速入门 > 迁移项目](https://support.huaweicloud.com/qs-ugo/ugo_02_0008.html)。 ## 3.SDK获取和安装 您可以通过Maven配置所依赖的SDK,具体的SDK版本号请参见[SDK开发中心](https://sdkcenter.developer.huaweicloud.com/?language=java) 。 ```xml com.huaweicloud.sdk huaweicloud-sdk-ugo 3.0.104 ``` ## 4.流程图 ![迁移项目的流程图](./assets/migration_project.jpg) ## 5.示例代码 以下代码展示如何使用SDK创建迁移项目,将源数据库SQL转换为目标数据库兼容的SQL,迁移转换后的SQL: ```java /* * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. */ package com.huawei.demo; import com.huaweicloud.sdk.core.auth.BasicCredentials; import com.huaweicloud.sdk.core.http.HttpConfig; import com.huaweicloud.sdk.ugo.v1.UgoClient; import com.huaweicloud.sdk.ugo.v1.model.CommitSyntaxConversionRequest; import com.huaweicloud.sdk.ugo.v1.model.CommitVerificationRequest; import com.huaweicloud.sdk.ugo.v1.model.CreateMigrationProject; import com.huaweicloud.sdk.ugo.v1.model.CreateMigrationProjectRequest; import com.huaweicloud.sdk.ugo.v1.model.DeleteMigrationProjectRequest; import com.huaweicloud.sdk.ugo.v1.model.DownloadFailureReportRequest; import com.huaweicloud.sdk.ugo.v1.model.ListMigrationProjectsRequest; import com.huaweicloud.sdk.ugo.v1.model.ListMigrationProjectsResponse; import com.huaweicloud.sdk.ugo.v1.model.ListPermissionCheckResultRequest; import com.huaweicloud.sdk.ugo.v1.model.ListSyntaxConversionProgressRequest; import com.huaweicloud.sdk.ugo.v1.model.ListSyntaxConversionProgressResponse; import com.huaweicloud.sdk.ugo.v1.model.ListVerificationProgressRequest; import com.huaweicloud.sdk.ugo.v1.model.ListVerificationProgressResponse; import com.huaweicloud.sdk.ugo.v1.model.MigrationProject; import com.huaweicloud.sdk.ugo.v1.model.ShowMigrationProjectDetailRequest; import com.huaweicloud.sdk.ugo.v1.model.ShowMigrationProjectStatusRequest; import com.huaweicloud.sdk.ugo.v1.model.ShowMigrationProjectStatusResponse; import com.huaweicloud.sdk.ugo.v1.model.TargetDBInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; /** * 数据库和应用迁移 UGO的示例代码:对象迁移 * * @since 2022-08-20 */ public class MigrationProjectDemo { private static final Logger logger = LoggerFactory.getLogger(SqlConvertDemo.class); public static void main(String[] args) throws InterruptedException { UgoClient ugoClient = getUgoClient(); String migrationProjectName = ""; String targetDBInstanceId = ""; String targetDBUserName = ""; String targetDBPassword = ""; String targetDBServiceName = ""; Integer evaluationProjectId = ""; TargetDBInfo targetDBInfo = new TargetDBInfo(); targetDBInfo.setInstanceId(targetDBInstanceId); targetDBInfo.setUserName(targetDBUserName); targetDBInfo.setPassword(targetDBPassword); targetDBInfo.setServiceName(targetDBServiceName); // Step 1: Create ugo migration project. createMigrationProject(ugoClient, migrationProjectName, evaluationProjectId, targetDBInfo); // Step 2: Get migration project list. String migrationProjectId = getMigrationProjectId(ugoClient, migrationProjectName); // Step 3: Check migration project status. checkMigrationProjectStatus(ugoClient, migrationProjectId); // Step 4: Get target db permission check result. ListPermissionCheckResultRequest listPermissionCheckResultRequest = new ListPermissionCheckResultRequest(); listPermissionCheckResultRequest.setMigrationProjectId(migrationProjectId); ugoClient.listPermissionCheckResult(listPermissionCheckResultRequest); // Step 5: Get migration project detail. ShowMigrationProjectDetailRequest showMigrationProjectDetailRequest = new ShowMigrationProjectDetailRequest(); showMigrationProjectDetailRequest.setMigrationProjectId(migrationProjectId); ugoClient.showMigrationProjectDetail(showMigrationProjectDetailRequest); // Step 6: Start to syntax conversion. CommitSyntaxConversionRequest commitSyntaxConversionRequest = new CommitSyntaxConversionRequest(); commitSyntaxConversionRequest.setMigrationProjectId(migrationProjectId); ugoClient.commitSyntaxConversion(commitSyntaxConversionRequest); // Step 7: Check syntax conversion progress. checkSyntaxConversionProgress(ugoClient, migrationProjectId); // Step 8: Start to verification. CommitVerificationRequest commitVerificationRequest = new CommitVerificationRequest(); commitVerificationRequest.setMigrationProjectId(migrationProjectId); ugoClient.commitVerification(commitVerificationRequest); // Step 9: Check verification progress. checkVerificationProgress(ugoClient, migrationProjectId); // Step 10: Download failure report. DownloadFailureReportRequest downloadFailureReportRequest = new DownloadFailureReportRequest(); downloadFailureReportRequest.setMigrationProjectId(migrationProjectId); ugoClient.downloadFailureReport(downloadFailureReportRequest); // Step 11: Delete migration project. DeleteMigrationProjectRequest deleteMigrationProjectRequest = new DeleteMigrationProjectRequest(); deleteMigrationProjectRequest.setMigrationProjectId(migrationProjectId); ugoClient.deleteMigrationProject(deleteMigrationProjectRequest); } private static UgoClient getUgoClient() { // 认证用的ak和sk直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; // 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 String ak = System.getenv("HUAWEICLOUD_SDK_AK"); String sk = System.getenv("HUAWEICLOUD_SDK_SK"); String endpoint = ""; String projectId = ""; // Http Configuration for client HttpConfig config = HttpConfig.getDefaultHttpConfig(); config.withIgnoreSSLVerification(true); // Create the authentication BasicCredentials auth = new BasicCredentials() .withAk(ak) .withSk(sk) .withProjectId(projectId); // Create UgoClient instance return UgoClient.newBuilder() .withHttpConfig(config) .withCredential(auth) .withEndpoint(endpoint) .build(); } private static void createMigrationProject(UgoClient ugoClient, String migrationProjectName, Integer evaluationProjectId, TargetDBInfo targetDBInfo) { CreateMigrationProjectRequest createMigrationProjectRequest = new CreateMigrationProjectRequest(); CreateMigrationProject createMigrationProjectBody = new CreateMigrationProject(); createMigrationProjectBody.setEvaluationProjectId(evaluationProjectId); createMigrationProjectBody.setMigrationProjectName(migrationProjectName); createMigrationProjectBody.setTargetDbInfo(targetDBInfo); createMigrationProjectBody.setOpenGaussConfig(null); createMigrationProjectRequest.setBody(createMigrationProjectBody); ugoClient.createMigrationProject(createMigrationProjectRequest); } private static void checkMigrationProjectStatus(UgoClient ugoClient, String migrationProjectId) throws InterruptedException { ShowMigrationProjectStatusRequest showMigrationProjectStatusRequest = new ShowMigrationProjectStatusRequest(); showMigrationProjectStatusRequest.setMigrationProjectId(migrationProjectId); while (true) { ShowMigrationProjectStatusResponse showMigrationProjectStatusResponse = ugoClient.showMigrationProjectStatus(showMigrationProjectStatusRequest); String readyStatus = ShowMigrationProjectStatusResponse.MigrationProjectStatusEnum.READY.getValue(); ShowMigrationProjectStatusResponse.MigrationProjectStatusEnum migrationProjectStatus = showMigrationProjectStatusResponse.getMigrationProjectStatus(); ShowMigrationProjectStatusResponse.PermissionCheckStatusEnum permissionCheckStatus = showMigrationProjectStatusResponse.getPermissionCheckStatus(); if (!readyStatus.equals(migrationProjectStatus.getValue())) { logger.info("migration project is not ready, permission check status: {}", permissionCheckStatus.getValue()); Thread.sleep(2000); continue; } logger.info("migration project is ready"); break; } } private static String getMigrationProjectId(UgoClient ugoClient, String migrationProjectName) throws InterruptedException { ListMigrationProjectsRequest listMigrationProjectsRequest = new ListMigrationProjectsRequest(); Integer migrationProjectId = null; OUT: while (true) { ListMigrationProjectsResponse listMigrationProjectsResponse = ugoClient.listMigrationProjects(listMigrationProjectsRequest); List migrationProjects = listMigrationProjectsResponse.getMigrationProjects(); for (MigrationProject project : migrationProjects) { if (!migrationProjectName.equals(project.getMigrationProjectName())) { Thread.sleep(2000); continue; } logger.info("create ugo migration project success."); migrationProjectId = project.getMigrationProjectId(); break OUT; } } return Integer.toString(migrationProjectId); } private static void checkSyntaxConversionProgress(UgoClient ugoClient, String migrationProjectId) throws InterruptedException { ListSyntaxConversionProgressRequest listSyntaxConversionProgressRequest = new ListSyntaxConversionProgressRequest(); listSyntaxConversionProgressRequest.setMigrationProjectId(migrationProjectId); while (true) { ListSyntaxConversionProgressResponse listSyntaxConversionProgressResponse = ugoClient.listSyntaxConversionProgress(listSyntaxConversionProgressRequest); Integer completedObjectsCount = listSyntaxConversionProgressResponse.getCompletedObjectsCount(); Integer totalObjectsCount = listSyntaxConversionProgressResponse.getTotalObjectsCount(); if (completedObjectsCount.equals(totalObjectsCount)) { logger.info("syntax conversion success."); break; } logger.info("syntax conversion in progress, total:{}, completed:{}.", totalObjectsCount, completedObjectsCount); Thread.sleep(5000); } } private static void checkVerificationProgress(UgoClient ugoClient, String migrationProjectId) throws InterruptedException { ListVerificationProgressRequest listVerificationProgressRequest = new ListVerificationProgressRequest(); listVerificationProgressRequest.setMigrationProjectId(migrationProjectId); while (true) { ListVerificationProgressResponse listVerificationProgressResponse = ugoClient.listVerificationProgress(listVerificationProgressRequest); Integer completedObjectsCount = listVerificationProgressResponse.getCompletedObjectsCount(); Integer totalObjectsCount = listVerificationProgressResponse.getTotalObjectsCount(); if (completedObjectsCount.equals(totalObjectsCount)) { logger.info("verification success."); break; } logger.info("verification in progress, total:{}, completed:{}.", totalObjectsCount, completedObjectsCount); Thread.sleep(5000); } } } ``` ## 6.返回结果示例 - 创建迁移项目(CreateMigrationProject)接口的返回值:无返回 - 查询迁移项目列表(ListMigrationProjects)接口的返回值: ``` { "migration_projects":[ { "migration_project_id":243, "migration_project_name":"Huawei-Codelabs-UGO-Migration-test", "evaluation_project_id":187, "evaluation_project_name":"Huawei-Codelabs-UGO-Evaluation-test", "migration_project_status":"READY", "permission_check_status":"SUCCESS", "resource_id":"28c045f5-7941-4a2c-85d2-8587334bcacc", "created_time":"2022-06-20T06:38:52Z", "updated_time":"2022-06-20T06:38:52Z" } ], "total_count":1 } ``` - 查询迁移项目状态(ShowMigrationProjectStatus)接口的返回值: ``` { "migration_project_id":243, "migration_project_name":"Huawei-Codelabs-UGO-Migration-test", "evaluation_project_id":187, "evaluation_project_name":"Huawei-Codelabs-UGO-Evaluation-test", "migration_project_status":"READY", "permission_check_status":"SUCCESS", "resource_id":"28c045f5-7941-4a2c-85d2-8587334bcacc", "created_time":"2022-06-20T06:38:52Z", "updated_time":"2022-06-20T06:38:52Z" } ``` - 查询权限检查结果(ListPermissionCheckResult)接口的返回值: ``` { "total_count":4, "passed_permission_items":[ { "permission_type":"MATERIALIZED_VIEW Create Permission", "schema_name":"SYNTAX_MIG_SCHEMA", "description":"Permission to Create/Drop MATERIALIZED_VIEW", "status":"alarm", "failed_reason":"Permission not found.", "failed_detail":"User does not have the permission to Create/Drop/Alter TABLE", "suggest_solution":[ "Provide user with Create/Drop/Alter Privilege, for example:- GRANT CREATE, DROP, ALTER ON *.* TO \"{user}\"@\"{host}\";" ] }, { "permission_type":"SUPERUSER Privilege", "schema_name":"", "description":"Check whether user has the super user privilege", "status":"alarm", "failed_reason":"Permission not found.", "failed_detail":"User does not have Super User privilege", "suggest_solution":[ "Provide user with Super User Privilege, for example:- GRANT SUPER ON *.* TO \"{user}\"@\"{host}\";" ] } ], "alarm_permission_items":[ { "permission_type":"MATERIALIZED_VIEW Create Permission", "schema_name":"SYNTAX_MIG_SCHEMA", "description":"Permission to Create/Drop MATERIALIZED_VIEW", "status":"alarm", "failed_reason":"Permission not found.", "failed_detail":"User does not have the permission to Create/Drop/Alter TABLE", "suggest_solution":[ "Provide user with Create/Drop/Alter Privilege, for example:- GRANT CREATE, DROP, ALTER ON *.* TO \"{user}\"@\"{host}\";" ] }, { "permission_type":"SUPERUSER Privilege", "schema_name":"", "description":"Check whether user has the super user privilege", "status":"alarm", "failed_reason":"Permission not found.", "failed_detail":"User does not have Super User privilege", "suggest_solution":[ "Provide user with Super User Privilege, for example:- GRANT SUPER ON *.* TO \"{user}\"@\"{host}\";" ] } ], "passed_count":0, "alarm_count":4 } ``` - 查询迁移项目详情(ShowMigrationProjectDetail)接口的返回值: ``` { "migration_project_id":243, "migration_project_name":"Huawei-Codelabs-UGO-Migration-test", "evaluation_project_name":"Huawei-Codelabs-UGO-Evaluation-test", "source_db_info":{ "connection_string":"100.xx.xxx.xxx:1521:ORCL", "ip":"", "port":"", "service_name":"", "user_name":"ugo" }, "target_db_info":{ "connection_string":"", "ip":"19x.1x8.x.96", "port":"3306", "service_name":"ugo", "user_name":"root" }, "created_time":"2022-06-20T04:11:13Z", "updated_time":"2022-06-20T04:11:13Z" } ``` - 提交语法转换(CommitSyntaxConversion)接口的返回值:无返回 - 查询语法转换的进度(ListSyntaxConversionProgress)接口的返回值: ``` { "total_objects_count":11, "completed_objects_count":11, "objects_list":[ { "object_type":"FUNCTION", "total_count":6, "succeed_count":6, "failed_count":0, "ignored_count":0, "manual_count":0, "success_rate":"100.00%" }, { "object_type":"GRANT", "total_count":5, "succeed_count":3, "failed_count":2, "ignored_count":0, "manual_count":0, "success_rate":"60.00%" } ] } ``` - 提交验证(CommitVerification)接口的返回值:无返回 - 查询验证进度(ListVerificationProgress)接口的返回值: ``` { "total_objects_count":6, "completed_objects_count":4, "objects_list":[ { "object_type":"FUNCTION", "total_count":4, "succeed_count":3, "failed_count":1, "ignored_count":0, "manual_count":0, "success_rate":"75.00%" }, { "object_type":"GRANT", "total_count":2, "succeed_count":0, "failed_count":0, "ignored_count":0, "manual_count":0, "success_rate":"0.00%" } ] } ``` - 下载迁移错误报告(DownloadFailureReport)接口的返回值:文件 - 删除迁移项目(DeleteMigrationProject)接口的返回值: ``` { "migration_project_id":"243" } ``` ## 7.参考链接 更多信息请参考[API Explorer](https://apiexplorer.developer.huaweicloud.com/apiexplorer/sdk?product=ugo) 和数据库和应用迁移 UGO服务文档的[API参考](https://support.huaweicloud.com/api-ugo/ugo_05_0002.html)。 ## 修订记录 | 发布日期 | 文档版本 | 修订说明 | | :--------: | :------: | :----------: | | 2022-09-22 | 1.0 | 文档首次发布 |