依赖管理

  <!-- 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的更多相关文章

  1. solr8.0 springboot整合solr(四)

    引言: solr搭建起后,就该应用到java后台开发里了,接下来就用springboot整合应用solr 一:引入jar包 <!--solr--> <dependency> & ...

  2. 搭建 springboot 2.0 mybatis 读写分离 配置区分不同环境

    最近公司打算使用springboot2.0, springboot支持HTTP/2,所以提前先搭建一下环境.网上很多都在springboot1.5实现的,所以还是有些差异的.接下来咱们一块看一下. 文 ...

  3. Springboot 系列(十六)你真的了解 Swagger 文档吗?

    前言 目前来说,在 Java 领域使用 Springboot 构建微服务是比较流行的,在构建微服务时,我们大多数会选择暴漏一个 REST API 以供调用.又或者公司采用前后端分离的开发模式,让前端和 ...

  4. SpringBoot笔记一

    1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库 ...

  5. springboot 开发入门,及问题汇总

    1 . springboot简单介绍(http://projects.spring.io/spring-boot/) 现在的web项目几乎都会用到spring框架,而要使用spring难免需要配置大量 ...

  6. Spring Boot 2.0 教程 - 深入SpringAplication

    原文连接:https://www.codemore.top/cates/Backend/post/2018-05-20/spring-boot-SpringApplication 可以通过Spring ...

  7. 使用kbmmw 生成REST 服务OpenAPI函数原型

    我们以前介绍了很多kbmmw 开发REST 的例子.一直有个问题困惑着大家. 我们提供REST 服务,如何让客户端快速的使用,当然可以写文档,但是一旦 后台改变了,又要再一次给调用者发新文档,非常的麻 ...

  8. 初识elasticsearch_2(查询和整合springboot)

    初始化 首先将官网所下载的json文件,放入到es中,采用如下命令: curl -H "Content-Type: application/json" -XPOST 'localh ...

  9. springboot 整合 Redis 方法二

    方法一请参考之前博文 spring boot 整合 redis 自己的版本  java8 + redis3.0 + springboot 2.0.0 1 spring boot已经支持集成 redis ...

  10. OpenAPI初体验

    问题的一开始源于客户和服务部门抱怨我的REST API文档写得不好,然后又了解到 django rest framework 利用 coreapi 能自动生成文档,再就是看到 swagger.io 上 ...

随机推荐

  1. 使用containerd从0搭建k8s(kubernetes)集群

    准备环境 准备两台服务器节点,如果需要安装虚拟机,可以参考<wmware和centos安装过程> 机器名 IP 角色 CPU 内存 centos01 192.168.109.130 mas ...

  2. HStore表全了解:实时入库与高效查询利器

    摘要:本文章将从使用者角度介绍HStore概念以及使用. 本文分享自华为云社区<GaussDB(DWS)HStore表讲解>,作者:大威天龙:- . HStore表简介 面对实时入库和实时 ...

  3. 教你学会使用Angular 应用里的 export declare const X Y

    摘要:export declare const X: Y语法用于在Angular应用程序中声明一个具有指定类型的常量变量,并将其导出,以便在其他文件中使用. 本文分享自华为云社区<关于 Angu ...

  4. Codeforces Round #882 (Div. 2) A-D

    比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; int a[107]; int ...

  5. 备份Ubunut已安装的软件包并在新的Ubuntu 系统上恢复

    0.查看已安装列表 dpkg -L xxxx.deb 1.备份 安装apt-clone: $sudo apt-get install apt-clone 提供一个保存备份文件的位置.我们在 /back ...

  6. RDB初步了解

    RDB概念 快照文件是.rdb结尾 redis6.2以前和之后(包括6.2)在什么条件下会保存rdb文件有所不同 以前 15min&&1个key(改变)调用保存 5min&&a ...

  7. SSH远程主机执行命令:s2c

    #!/bin/bash ip=$1 ip_num=$(echo $ip | awk -F\. '{print NF}') if [ $ip_num -eq 2 ]; then ip=192.168.$ ...

  8. WebStorm: 配置React中useState自动补齐功能

    配置如下 模板文本如下所示 const [$STATE$, $SET_STATE$] = useState($INITAL_STATE$) 编辑变量 SET_STATE文本如下所示 concat(&q ...

  9. 什么是PMP?

    PMP(Project Management Professional)中文名称叫项目管理专业人士资格认证.它是由美国项目管理协会(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证 ...

  10. cesium中文网

    http://cesium.xin/cesium/cn/Documentation1.62/CallbackProperty.html