Apollo2.1.0+Springboot使用OpenApI
依赖管理
<!-- bootstrap最高级启动配置读取 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>2.1.0</version>
</dependency>
application.properties
# Apollo
app.id=MORE-USER-USE
apollo.cache-dir=./ManyUser/apollo/cache
apollo.bootstrap.enabled=true
#apollo.bootstrap.namespaces=application.properties
apollo.meta=http://localhost:8080
apollo.bootstrap.eagerLoad.enabled=true
apollo.config-service=http://localhost:8080
env=DEV
apollo.use.admin.token=809d168da6f3baa39c02c1d376a0cc9cec852fa0fa8c6e2cff9b33e276d3738a
apollo.use.portal.url=http://localhost:8070
apollo-env.properties
dev.meta=http://localhost:8080
启动类 加入 @EnableApolloConfig
/**
* @description: 启动类
* @author: GuoTong
* @createTime: 2023-06-21 20:31
* @since JDK 1.8 OR 11
**/
@SpringBootApplication
@EnableApolloConfig
public class AppStartClass {
public static void main(String[] args) {
SpringApplication.run(AppStartClass.class, args);
}
}
常规配置中心集成使用
package com.gton.user.config;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import com.gton.user.io.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @description: Apollo同时还增加了几个新的Annotation来简化在Spring环境中的使用。
* @author: GuoTong
* @createTime: 2023-06-24 12:30
* @since JDK 1.8 OR 11
**/
@Component
@Slf4j
public class MyApolloConfig {
/**
* ApolloJsonValue annotated on fields example, the default value is specified as empty list - []
* <br />
* jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue("${jsonBeanProperty:[]}")
private List<Resp> anotherJsonBeans = new ArrayList<>();
@Value("${batch:100}")
private String batch;
//config change listener for namespace application
@ApolloConfigChangeListener(value = "application")
private void apolloChange(ConfigChangeEvent changeEvent) {
//update injected value of batch if it is changed in Apollo
if (changeEvent.isChanged("batch")) {
batch = changeEvent.getChange("batch").getNewValue();
}
log.info(changeEvent.getNamespace() + "变化的key=>" + changeEvent.changedKeys() + ";==1");
}
@ApolloConfigChangeListener(value = "order")
private void someOnChange(ConfigChangeEvent changeEvent) {
//update injected value of batch if it is changed in Apollo
if (changeEvent.isChanged("anotherJsonBeans")) {
log.info(changeEvent.getChange("anotherJsonBeans").getOldValue());
log.error(changeEvent.getChange("anotherJsonBeans").getNewValue());
}
log.info(anotherJsonBeans.toString());
log.info(changeEvent.getNamespace() + "变化的key=>" + changeEvent.changedKeys() + ";==1");
}
}
Apollo 的开放平台使用
package com.gton.user.handler;
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenAppNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenPageDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;
/**
* @description: Apollo开放平台操作
* @author: GuoTong
* @createTime: 2023-06-24 14:10
* @since JDK 1.8 OR 11
**/
public class ApolloOpenApiOperator {
private ApolloOpenApiClient apolloOpenApiClient;
private static ApolloOpenApiOperator apolloOpenApiOperator = null;
public static ApolloOpenApiOperator getApolloOpenApiOperator() throws IOException {
if (apolloOpenApiOperator == null) {
synchronized (ApolloOpenApiOperator.class) {
if (apolloOpenApiOperator == null) {
return new ApolloOpenApiOperator();
}
}
}
return apolloOpenApiOperator;
}
public ApolloOpenApiOperator(ApolloOpenApiClient apolloOpenApiClient) {
this.apolloOpenApiClient = apolloOpenApiClient;
}
public ApolloOpenApiOperator() throws IOException {
initApolloOpenApiOperator();
}
private void initApolloOpenApiOperator() throws IOException {
// 获取配置文件
ClassPathResource classPathResource = new ClassPathResource("application.properties");
InputStream inputStream = classPathResource.getInputStream();
// 使用properties加载
Properties properties = new Properties();
properties.load(inputStream);
String token = properties.getProperty("apollo.use.admin.token");
String portalUrl = properties.getProperty("apollo.use.portal.url");
if (StringUtils.isNotEmpty(token)) {
this.apolloOpenApiClient = ApolloOpenApiClient
.newBuilder().
withConnectTimeout(60000).
withToken(token).
withPortalUrl(portalUrl).
withReadTimeout(60000)
.build();
}
}
public ApolloOpenApiClient getApolloOpenApiClient() {
return this.apolloOpenApiClient;
}
/**
* Description: 创建NamSpace
*
* @param openAppNamespaceKey
* @author: GuoTong
* @date: 2023-06-24 15:04:44
* @return:void
*/
public void crateNameSpace(OpenAppNamespaceKey openAppNamespaceKey) {
OpenAppNamespaceDTO openAppNamespaceDTO = new OpenAppNamespaceDTO();
openAppNamespaceDTO.setAppId(openAppNamespaceKey.getAppId());
openAppNamespaceDTO.setName(openAppNamespaceKey.getSpaceName());
openAppNamespaceDTO.setComment(openAppNamespaceKey.getSpaceDesc());
openAppNamespaceDTO.setPublic(openAppNamespaceKey.spaceIsPub);
apolloOpenApiClient.createAppNamespace(openAppNamespaceDTO);
}
/**
* Description: 下发Apollo
*
* @param doIssueApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:35:52
* @return:void
*/
public void doIssueApollo(DoIssueApolloKey doIssueApolloKey) {
OpenItemDTO openItemDTO = new OpenItemDTO();
openItemDTO.setKey(doIssueApolloKey.getKey());
openItemDTO.setValue(doIssueApolloKey.getValue());
openItemDTO.setComment(doIssueApolloKey.getDesc());
openItemDTO.setType(doIssueApolloKey.handlerValueType(doIssueApolloKey.getValueType()));
openItemDTO.setDataChangeCreatedBy(doIssueApolloKey.getOperator());
if (doIssueApolloKey.isModifiedOrInsert()) {
openItemDTO.setDataChangeLastModifiedBy(doIssueApolloKey.getOperator());
}
// 下发到Apollo
apolloOpenApiClient.createOrUpdateItem(
doIssueApolloKey.getAppId(),
doIssueApolloKey.getEnv(),
doIssueApolloKey.getClusterName(),
doIssueApolloKey.getNamespaceName(),
openItemDTO
);
}
/**
* Description: 发布整个NameSpace;推荐下发完成之后统一调一次,不要多次的下发操作,每一次下发都调用
*
* @param publishApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public void executorPublish(PublishApolloKey publishApolloKey) {
// apollo下发的数据执行发布
NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
//配置版本名称
namespaceReleaseDTO.setReleaseTitle(publishApolloKey.getReleaseTitle());
// 发布说明
namespaceReleaseDTO.setReleaseComment(publishApolloKey.getReleaseDescription());
// 操作员
namespaceReleaseDTO.setReleasedBy(publishApolloKey.getReleaseOperator());
apolloOpenApiClient.publishNamespace(publishApolloKey.getAppId(),
publishApolloKey.getEnv(),
publishApolloKey.getClusterName(),
publishApolloKey.getNamespaceName(), namespaceReleaseDTO);
}
/**
* Description: 移除Apollo的配置
* String appId, String env, String clusterName, String namespaceName, String key,
* String operator
*
* @param removeKeys
* @author: GuoTong
* @date: 2023-06-24 15:27:07
* @return:void
*/
public void executorRemove(DoIssueApolloKey removeKeys) {
apolloOpenApiClient.removeItem(removeKeys.getAppId(),
removeKeys.getEnv(),
removeKeys.getClusterName(),
removeKeys.getNamespaceName(), removeKeys.getKey(), removeKeys.getOperator());
}
/**
* queryApolloKey many
*
* @param baseApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public List<OpenItemDTO> queryApolloKey(BaseApolloKey baseApolloKey, int page, int size) {
if (page <= 1) {
page = 0;
}
if (size <= 0) {
size = 10;
}
OpenPageDTO<OpenItemDTO> itemsByNamespace = apolloOpenApiClient.findItemsByNamespace(baseApolloKey.getAppId(),
baseApolloKey.getEnv(),
baseApolloKey.getClusterName(),
baseApolloKey.getNamespaceName(), page, size);
List<OpenItemDTO> content = itemsByNamespace.getContent();
return content;
}
/**
* queryApolloKey one
*
* @param baseApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public OpenItemDTO queryApolloKeyOne(DoIssueApolloKey baseApolloKey) {
OpenItemDTO itemsByNamespace = apolloOpenApiClient.getItem(baseApolloKey.getAppId(),
baseApolloKey.getEnv(),
baseApolloKey.getClusterName(),
baseApolloKey.getNamespaceName(), baseApolloKey.getKey());
return itemsByNamespace;
}
@Data
public static class OpenAppNamespaceKey {
private String appId;
private String spaceName;
private String spaceDesc;
private boolean spaceIsPub = false;
// 默认值 DEV
private String env = "DEV";
private String clusterName;
private String namespaceName;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class DoIssueApolloKey extends BaseApolloKey {
private String key;
private String value;
// 默认值 Apollo
private String operator = "Apollo";
private String desc;
private String valueType;
// 是否是修改
private boolean modifiedOrInsert;
/**
* Description: 查询 Portal web的前端得出
*
* @author: GuoTong
* @date: 2023-06-24 14:46:42
* <select class="form-control ng-valid ng-valid-valdr ng-not-empty ng-dirty ng-touched ng-valid-parse" name="type" ng-model="item.type" ng-change="changeType()">
* <option value="0" class="ng-binding">String</option>
* <option value="1" class="ng-binding">Number</option>
* <option value="2" class="ng-binding">Boolean</option>
* <option value="3" class="ng-binding">JSON</option>
* </select>
*/
public int handlerValueType(String valueType) {
switch (valueType) {
case "String":
return 0;
case "Number":
return 1;
case "Boolean":
return 2;
case "JSON":
return 3;
}
// 未匹配就默认使用String的值
return 0;
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class BaseApolloKey {
protected String appId;
// 默认值 DEV
protected String env = "DEV";
// 默认值 default
protected String clusterName = "default";
protected String namespaceName;
}
@Data
public static class PublishApolloKey extends BaseApolloKey {
// 发布时候的标题
private String releaseTitle;
// 发布时候的操作员
private String releaseOperator;
// 发布时候的DESC
private String releaseDescription;
}
}
配合Controller使用
package com.gton.user.controller;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.gton.user.annotation.SwaggerScanClass;
import com.gton.user.handler.ApolloOpenApiOperator;
import com.gton.user.io.Resp;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* 多租户表(apollo)表控制层
*
* @author 郭童
* @since 2023-06-22 16:28:10
*/
@RestController
@RequestMapping("apollo")
@SwaggerScanClass
public class ApolloOperatorController {
/**
* 分页查询数据 namespaceName
*
* @param
* @return 所有数据
*/
@PostMapping("/queryLimit")
@ApiOperation("查询Apollo配置")
public Resp<List<OpenItemDTO>> queryPage(
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName
) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.BaseApolloKey baseApolloKey = new ApolloOpenApiOperator.BaseApolloKey();
baseApolloKey.setAppId(appId);
baseApolloKey.setClusterName(clusterName);
baseApolloKey.setEnv(env);
baseApolloKey.setNamespaceName(namespaceName);
List<OpenItemDTO> openItemDTOS = apolloOpenApiOperator.queryApolloKey(baseApolloKey, 0, 10);
return Resp.Ok(openItemDTOS);
}
/**
* 通过主键查询单条数据
*
* @param key apollo-key
* @return 单条数据
*/
@GetMapping("/queryOne/{key}")
public Resp<OpenItemDTO> selectOne(@PathVariable("key") String key,
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.DoIssueApolloKey baseApolloKey = new ApolloOpenApiOperator.DoIssueApolloKey();
baseApolloKey.setAppId(appId);
baseApolloKey.setEnv(env);
baseApolloKey.setNamespaceName(namespaceName);
baseApolloKey.setClusterName(clusterName);
baseApolloKey.setKey(key);
OpenItemDTO openItemDTO = apolloOpenApiOperator.queryApolloKeyOne(baseApolloKey);
return Resp.Ok(openItemDTO);
}
/**
* 新增数据 到Apollo
*
* @param doIssueApolloKey 实体对象
* @return 新增结果
*/
@PostMapping("/save")
public Resp<String> insert(@RequestBody Map<String, String> doIssueApolloKey) throws IOException {
String json = JSON.toJSONString(doIssueApolloKey);
ApolloOpenApiOperator.DoIssueApolloKey doIssueApolloData = JSONObject.parseObject(json, ApolloOpenApiOperator.DoIssueApolloKey.class);
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
doIssueApolloData.setModifiedOrInsert(false);
apolloOpenApiOperator.doIssueApollo(doIssueApolloData);
return Resp.Ok(doIssueApolloData.getKey());
}
/**
* 修改数据
*
* @param doIssueApolloKey 实体对象
* @return 修改结果
*/
@PutMapping("/update")
public Resp<String> update(@RequestBody Map<String, String> doIssueApolloKey) throws IOException {
String json = JSON.toJSONString(doIssueApolloKey);
ApolloOpenApiOperator.DoIssueApolloKey doIssueApolloData = JSONObject.parseObject(json, ApolloOpenApiOperator.DoIssueApolloKey.class);
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
doIssueApolloData.setModifiedOrInsert(true);
apolloOpenApiOperator.doIssueApollo(doIssueApolloData);
return Resp.Ok(doIssueApolloData.getKey());
}
/**
* Description: 移出Apollo已下发数据
*
* @param key
* @param appId
* @param clusterName
* @param env
* @param namespaceName
* @author: GuoTong
* @date: 2023-06-24 15:42:24
* @return:com.gton.user.io.Resp<java.lang.String>
*/
@GetMapping("/dels")
public Resp<String> delete(@RequestParam("key") String key,
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.DoIssueApolloKey removeKeys = new ApolloOpenApiOperator.DoIssueApolloKey();
removeKeys.setAppId(appId);
removeKeys.setEnv(env);
removeKeys.setNamespaceName(namespaceName);
removeKeys.setClusterName(clusterName);
removeKeys.setKey(key);
apolloOpenApiOperator.executorRemove(removeKeys);
return Resp.Ok(removeKeys.getKey());
}
}
Apollo2.1.0+Springboot使用OpenApI的更多相关文章
- solr8.0 springboot整合solr(四)
引言: solr搭建起后,就该应用到java后台开发里了,接下来就用springboot整合应用solr 一:引入jar包 <!--solr--> <dependency> & ...
- 搭建 springboot 2.0 mybatis 读写分离 配置区分不同环境
最近公司打算使用springboot2.0, springboot支持HTTP/2,所以提前先搭建一下环境.网上很多都在springboot1.5实现的,所以还是有些差异的.接下来咱们一块看一下. 文 ...
- Springboot 系列(十六)你真的了解 Swagger 文档吗?
前言 目前来说,在 Java 领域使用 Springboot 构建微服务是比较流行的,在构建微服务时,我们大多数会选择暴漏一个 REST API 以供调用.又或者公司采用前后端分离的开发模式,让前端和 ...
- SpringBoot笔记一
1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库 ...
- springboot 开发入门,及问题汇总
1 . springboot简单介绍(http://projects.spring.io/spring-boot/) 现在的web项目几乎都会用到spring框架,而要使用spring难免需要配置大量 ...
- Spring Boot 2.0 教程 - 深入SpringAplication
原文连接:https://www.codemore.top/cates/Backend/post/2018-05-20/spring-boot-SpringApplication 可以通过Spring ...
- 使用kbmmw 生成REST 服务OpenAPI函数原型
我们以前介绍了很多kbmmw 开发REST 的例子.一直有个问题困惑着大家. 我们提供REST 服务,如何让客户端快速的使用,当然可以写文档,但是一旦 后台改变了,又要再一次给调用者发新文档,非常的麻 ...
- 初识elasticsearch_2(查询和整合springboot)
初始化 首先将官网所下载的json文件,放入到es中,采用如下命令: curl -H "Content-Type: application/json" -XPOST 'localh ...
- springboot 整合 Redis 方法二
方法一请参考之前博文 spring boot 整合 redis 自己的版本 java8 + redis3.0 + springboot 2.0.0 1 spring boot已经支持集成 redis ...
- OpenAPI初体验
问题的一开始源于客户和服务部门抱怨我的REST API文档写得不好,然后又了解到 django rest framework 利用 coreapi 能自动生成文档,再就是看到 swagger.io 上 ...
随机推荐
- 使用containerd从0搭建k8s(kubernetes)集群
准备环境 准备两台服务器节点,如果需要安装虚拟机,可以参考<wmware和centos安装过程> 机器名 IP 角色 CPU 内存 centos01 192.168.109.130 mas ...
- HStore表全了解:实时入库与高效查询利器
摘要:本文章将从使用者角度介绍HStore概念以及使用. 本文分享自华为云社区<GaussDB(DWS)HStore表讲解>,作者:大威天龙:- . HStore表简介 面对实时入库和实时 ...
- 教你学会使用Angular 应用里的 export declare const X Y
摘要:export declare const X: Y语法用于在Angular应用程序中声明一个具有指定类型的常量变量,并将其导出,以便在其他文件中使用. 本文分享自华为云社区<关于 Angu ...
- Codeforces Round #882 (Div. 2) A-D
比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; int a[107]; int ...
- 备份Ubunut已安装的软件包并在新的Ubuntu 系统上恢复
0.查看已安装列表 dpkg -L xxxx.deb 1.备份 安装apt-clone: $sudo apt-get install apt-clone 提供一个保存备份文件的位置.我们在 /back ...
- RDB初步了解
RDB概念 快照文件是.rdb结尾 redis6.2以前和之后(包括6.2)在什么条件下会保存rdb文件有所不同 以前 15min&&1个key(改变)调用保存 5min&&a ...
- SSH远程主机执行命令:s2c
#!/bin/bash ip=$1 ip_num=$(echo $ip | awk -F\. '{print NF}') if [ $ip_num -eq 2 ]; then ip=192.168.$ ...
- WebStorm: 配置React中useState自动补齐功能
配置如下 模板文本如下所示 const [$STATE$, $SET_STATE$] = useState($INITAL_STATE$) 编辑变量 SET_STATE文本如下所示 concat(&q ...
- 什么是PMP?
PMP(Project Management Professional)中文名称叫项目管理专业人士资格认证.它是由美国项目管理协会(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证 ...
- cesium中文网
http://cesium.xin/cesium/cn/Documentation1.62/CallbackProperty.html