开发业务代码
准备工作
- 已下载并安装Maven,根据以下步骤配置Maven。
- 在<localRepository>标签内添加自己的本地仓库位置路径,这个本地仓库位置是自己创建的。
D:\apache-maven-3.8.6-bin\repository
<localRepository>D:\apache-maven-3.8.6-bin\repository</localRepository>
- 修改maven默认的JDK版本。
在<profiles>标签下添加一个<profile>标签,修改maven默认的JDK版本。
<profile> <id>JDK-1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile>
- 在<localRepository>标签内添加自己的本地仓库位置路径,这个本地仓库位置是自己创建的。
- 安装并配置IntelliJ IDEA开发工具。
- 在IntelliJ IDEA中选择File > Settings > Bulid,Execution,Deployment > Bulid Tools > Maven。
- 在User settings file中配置setting.xml。
- 在Local repository中配置自定义的Maven仓库地址。
- JAVA开发环境的配置。
AppStage提供的SDK是基于java1.8版本开发的,如果Spring Cloud项目使用java11及以上版本,则不支持使用AppStage提供的SDK进行应用开发。以下步骤以win7环境配置JDK8 64位为例,若已经下载JDK并配置好环境请跳过本步骤。
- 下载JDK文件。
- 下载完成后按照提示安装,位置自选,比如安装到本地C:\Program Files\Java\jdk1.8.0_131。
- 配置Java环境变量:右键“计算机>属性>高级系统设置>环境变量”,进行如下操作。
- 新建系统变量JAVA_HOME,变量值为实际JDK安装位置。
- 在Path中添加%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin (注意用英文分号分隔)。
- 新建系统变量CLASSPATH,变量值为%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar。
- 打开命令行窗口,输入“java -version”,显示如图1表示配置成功。
- 获取SDK并进行完整性校验。
操作步骤
- 打开本地Spring Cloud项目。
- 手动导入SDK jar包。
- 在项目目录下新建一个lib目录,存放jar包。
- 将本地的jar包复制粘贴至lib目录下。
- 将jar导入到项目中。
- 选择“File>Project Structure> Project Settings>Module”。
- 单击“+”,选择“JARs or Directories...”。
- 选中jar包,单击“apply”。导包完成。
- (可选)集成OrgID登录功能。
DemoOrgidLogin项目用于对接OrgID组织成员账号服务,对接后可以使用OrgID服务完成自身应用的登录、组织管理功能。具体请参考集成OrgID登录功能。
- 配置微服务。
- 微服务接入STS。
STS提供了微服务之间请求认证以及敏感配置项管理的功能,STS是接入Cloud Map的前提条件,Cloud Map依赖STS认证能力。
- 将在AppStage业务控制台中创建的DemoOrgidLogin、DemoServiceAService、DemoServiceBService注册到运维中心的ACMS管理台中,具体请参见微服务注册。
图2 注册微服务
- 在DemoOrgidLogin、DemoServiceA、DemoServiceB的pom.xml中添加STS依赖。
- 如果将SDK放到外部maven仓中,则只需要添加sts-spring-boot依赖。
- 本例是以本地依赖的方式引入SDK,即手动将本地下载的SDK jar包引入到工程的lib目录下,需要添加的依赖如下所示。实际需要依赖的包只有sts-spring-boot,其他均是间接依赖,若启动过程中需要其他开源依赖也需要手动加入。
<dependency> <groupId>com.huawei.wisecloud.sts</groupId> <artifactId>sts-spring-boot</artifactId> <version>1.1.19.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/sts-spring-boot-1.1.19.100.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.sts</groupId> <artifactId>sts-key-sdk</artifactId> <version>1.1.19.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/sts-key-sdk-1.1.19.100.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.sts</groupId> <artifactId>sts-sdk-base</artifactId> <version>1.1.19.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/sts-sdk-base-1.1.19.100.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.kms</groupId> <artifactId>cloudsoa-security</artifactId> <version>1.1.14.101</version> <scope>system</scope> <systemPath>${project.basedir}/lib/cloudsoa-security-1.1.14.101.jar</systemPath> </dependency>
- 增加STS配置项。
在DemoOrgidLogin、DemoServiceA、DemoServiceB的ClassPath下增加application.properties配置文件,本实践配置项如下:
sts.server.domain=10.33.102.162:8080 #STS接入地址 sts.config.path=/opt/huawei/certs/jamesService22A/DemoServiceAService/DemoServiceAService.ini #STS微服务证书路径,IaC3.0会将证书放在固定路径下,格式为/opt/huawei/certs/服务名/微服务名/微服务名.ini
- 启动STS。
在微服务的启动类中添加注解,本实践是在ServiceASpringbootApplication.java、ServiceBSpringbootApplication.java和DemoOrgidLogin的OrgLogin.java文件中添加@EnableStsAutoInitialization(value = "application.properties")注解。注解的含义是启动STS自动初始化,其中value是指定STS的配置文件路径。
- 将在AppStage业务控制台中创建的DemoOrgidLogin、DemoServiceAService、DemoServiceBService注册到运维中心的ACMS管理台中,具体请参见微服务注册。
- 敏感信息配置项托管。
- 使用STS的敏感配置项管理功能 ,需要在ACMS中录入敏感配置项,具体请参见录入敏感配置。
- 在IaC脚本中的业务配置项配置文件中指定敏感配置项取值路径。
- 在IaC脚本中的业务配置项属性定义文件中,声明该配置项为敏感配置项。
- 在配置文件中增加敏感配置项名称的配置。
- 启动敏感配置项自动解密。
使用OrgID登录时所需的客户端密钥,属于敏感配置项,需要使用STS的配置敏感配置项托管功能。本实践中配置如下:- 在ACMS中录入配置敏感配置项,如图3所示。
- 本实践在IaC脚本DemoOrgidLogin的业务配置项文件config_records.yaml增加一个名为spring.redis.password的敏感配置项,这个敏感配置项是访问Redis的密码。
spring.redis.password: MicroService/jamesService22A/DemoOrgidLogin/spring.redis.password/default #Redis访问密码,属于敏感配置项,已被STS(ACMS)纳管,配置路径为:MicroService/服务名/微服务名/敏感配置项名称/敏感配置项标签
- 本实践中访问Redis的密码spring.redis.password为敏感配置项,在IaC脚本DemoOrgidLogin的业务配置项属性定义文件config_schema.yaml中声明。
type: object properties: spring.redis.password: format: sensitive
- 在application.yml配置文件中增加敏感配置项名称的配置。
nuwa: security: config: sensitiveWords: spring.redis.password,org.app.protocol-login.oauth.clientSecret,org.app.jwt-key
- 在DemoOrgidLogin的启动类中添加注解,启动敏感配置项自动解密。本实践是在OrgLogin.java文件中添加@EnableStsEncryptableProperties注解。
- 微服务接入Cloud Map。
Spring Cloud通常是使用其自带的Eureka注册中心,接入AppStage可以将Eureka注册中心替换为Cloud Map,Cloud Map其优势为除了能够提供服务发现的功能,还可以提供数据库、敏感信息等的纳管功能。
- 在DemoOrgidLogin、DemoServiceA、DemoServiceB的pom.xml中添加Cloud Map依赖。
- 如果将SDK放到外部maven仓中,则只需要添加nuwa-cloudmap-core依赖。
- 本例是以本地依赖的方式引入SDK,即手动将本地下载的SDK jar包引入到工程的lib目录下,需要添加的依赖如下所示。实际需要依赖的包只有nuwa-cloudmap-core,其他均是间接依赖,若启动过程中需要其他开源依赖也需要手动加入。
<dependency> <groupId>com.huawei.wisecloud.nuwa</groupId> <artifactId>spring-cloud-starter-cloudmap-discovery</artifactId> <version>1.0.12.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/spring-cloud-starter-cloudmap-discovery-1.0.12.100.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.nuwa</groupId> <artifactId>nuwa-cloudmap-core</artifactId> <version>1.0.12.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/nuwa-cloudmap-core-1.0.12.100.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.nuwa</groupId> <artifactId>nuwa-cloudmap-spring-boot-starter</artifactId> <version>1.0.12.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/nuwa-cloudmap-spring-boot-starter-1.0.12.100.jar</systemPath> </dependency>
- 增加Cloud Map配置项。
本实践分别在DemoServiceA、DemoServiceB的application.yaml配置文件及DemoOrgidLogin的application.yml文件中添加以下配置项:
nuwa: cloudmap: read: cloudmap #使用Cloud Map方式进行微服务间通信 clusterName: SpringCloudDemo #微服务注册到Cloud Map的集群 provider: cluster: SpringCloudDemo #提供服务的其他同样被注册到Cloud Map的微服务集群名 serverAddr: http://10.34.32.243:80 #Cloud Map访问地址 version: 1.0.0.100 #微服务版本号 namespaceName: cn_dev_default #Cloud Map访问命名空间
- 启动初始化Cloud Map,将微服务注册到Cloud Map。
在微服务的启动类中添加注解,本实践是在ServiceASpringbootApplication.java、ServiceBSpringbootApplication.java和DemoOrgidLogin的OrgLogin.java文件中添加@EnableDiscoveryClient注解。同时在启动类中完成将RestTemplate注册到spring容器中,后续微服务间调用使用注册到spring容器中的RestTemplate,代码如下:
package com.huawei.demo.servicea; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; import com.huawei.wisesecurity.sts.springboot.security.annotation.EnableStsAutoInitialization; @SpringBootApplication @EnableStsAutoInitialization(value = "application.properties") @EnableDiscoveryClient public class ServiceASpringbootApplication { public static void main(String[] args) { SpringApplication.run(ServiceASpringbootApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
微服务间调用:
public OrderInfo findOrder(String orderId, HttpServletRequest request) { OrderInfo orderInfo = orderMapper.getOrderById(orderId); String url = demoServiceAUrl + "/user/" + orderInfo.getUserId(); HttpHeaders headers = createHeaders(request); HttpEntity<String> entity = new HttpEntity<>(null, headers); ResponseEntity<UserInfo> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, UserInfo.class); ; if (responseEntity != null) { orderInfo.setUserInfo(responseEntity.getBody()); } return orderInfo; }
- 在AppStage运维中心的Cloud Map中验证微服务注册,具体请参见查看微服务列表。
图4 验证微服务注册
- 在DemoOrgidLogin、DemoServiceA、DemoServiceB的pom.xml中添加Cloud Map依赖。
- 使用WiseDBA进行数据库纳管。
- 在AppStage运维中心的WiseDBA中申请数据库并创建Schema,具体请参见创建数据库实例及创建Schema。
本实践中申请的数据库性能规格为:独享型/gaussdb.mysql.large.x86.8/2vCPUs/16GB,数据库实例名称为:gauss-SpringCloudDemo2,DemoServiceAService和DemoServiceBService的Schema名称分别为:springclouddemoa、springclouddemob。
- 在WiseDBA管理台配置连接信息,并注册到Cloud Map中,在创建数据库连接时,直接调用Cloud Map中的注册信息。
- 在DemoServiceA和DemoServiceB的pom.xml中添加Rainbow SDK依赖。
- 如果将SDK放到外部maven仓中,则只需要添加rainbow-proxy依赖。
- 本例是以本地依赖的方式引入SDK,即手动将本地下载的SDK jar包引入到工程的lib目录下,需要添加的依赖如下所示。实际需要依赖的包只有rainbow-proxy,其他均是间接依赖,若启动过程中需要其他开源依赖也需要手动加入。
<dependency> <groupId>com.huawei.wisecloud.nuwa</groupId> <artifactId>rainbow-proxy</artifactId> <version>1.2.18.102</version> <scope>system</scope> <systemPath>${project.basedir}/lib/rainbow-proxy-1.2.18.102.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.nuwa</groupId> <artifactId>rainbow-core-drds</artifactId> <version>1.2.18.201</version> <scope>system</scope> <systemPath>${project.basedir}/lib/rainbow-core-drds-1.2.18.201.jar</systemPath> </dependency> <dependency> <groupId>com.huawei.wisecloud.gpaas</groupId> <artifactId>gpaas-middleware-common</artifactId> <version>2.2.6.100</version> <scope>system</scope> <systemPath>${project.basedir}/lib/gpaas-middleware-common-2.2.6.100.jar</systemPath> </dependency>
- 初始化Rainbow。
在DemoServiceA、DemoServiceB的com/huawei/demo/servicea/config/下添加ApplicationAutoConfig.java文件,代码如下:
package com.huawei.demo.serviceb.config; import javax.sql.DataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.support.TransactionTemplate; import com.huawei.nuwa.map.client.NuwaMapClient; import com.huawei.nuwa.map.spring.boot.autoconfigure.NuwaCloudMapAutoConfiguration; import com.huawei.rainbow.jdbc.DbGroupDataSource; import com.huawei.wisesecurity.sts.springboot.security.configuration.StsEncryptablePropertiesConfiguration; /** * Rainbow启动 */ @Configuration @Order(Ordered.HIGHEST_PRECEDENCE) @Import(value = {NuwaCloudMapAutoConfiguration.class, StsEncryptablePropertiesConfiguration.class}) public class ApplicationAutoConfig implements EnvironmentAware { private Environment environment; /** * Rainbow需要依赖STS和Cloud Map启动,创建dataSource * * @param client NuwaMapClient值对象 * @return DataSource 初始化完成的数据源数据源 */ @Bean @DependsOn({"stsBootStrap"}) public DataSource createDataSource(NuwaMapClient client) { DbGroupDataSource dataSource = new DbGroupDataSource(); dataSource.setUseSts(true); dataSource.setAppName(environment.getProperty("wiseDba.appName")); dataSource.setDbGroupKey(environment.getProperty("wiseDba.groupKey")); dataSource.setDbName(environment.getProperty("wiseDba.dbName")); dataSource.init(); return dataSource; } /** * 事务管理创建 * * @param dataSource 数据源 * @return DataSourceTransactionManager 事务管理 */ @Bean public DataSourceTransactionManager createTransaction(DataSource dataSource) { DataSourceTransactionManager transaction = new DataSourceTransactionManager(); transaction.setDataSource(dataSource); return transaction; } @Bean public JdbcTemplate createJdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean("sqlSessionFactoryBean") public SqlSessionFactoryBean createMybatisSqlSessionFactoryBean(DataSource dataSource) { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); // 数据源配置项 org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); //允许jdbc自动生成主键 configuration.setUseGeneratedKeys(true); // 使用列标签代替列名 configuration.setUseColumnLabel(true); // 打开下划线命名自动转换为驼峰命名开关 configuration.setMapUnderscoreToCamelCase(true); sessionFactoryBean.setConfiguration(configuration); return sessionFactoryBean; } @Bean public TransactionTemplate createTransactionTemplate(DataSourceTransactionManager dataSourceTransactionManager) { TransactionTemplate template = new TransactionTemplate(); template.setTransactionManager(dataSourceTransactionManager); return template; } @Bean public MapperScannerConfigurer createMapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("com.huawei.demo"); configurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); return configurer; } @Override public void setEnvironment(Environment environment) { this.environment = environment;
- 在AppStage运维中心的WiseDBA中申请数据库并创建Schema,具体请参见创建数据库实例及创建Schema。
- 微服务接入STS。