# nacos-plugin-ext
**Repository Path**: yanweiling/nacos-plugin-ext
## Basic Information
- **Project Name**: nacos-plugin-ext
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: nacos-ywl
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-12-31
- **Last Updated**: 2025-01-16
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# nacos-plugin
A collection of Nacos plug-ins that provide pluggable plug-in capabilities for Nacos and support user customization and high scalability

基于官方的nacos-plugin-ext,做了如下调整
基于dev 分支,
1.将oracle相关的module删除
2. 2.3.0-SNAPSHOT 将此版本改为:
2.4.0
3.初始化postgresql的脚本指定了schema,采用脚本nacos-pg-schema.sql
4.新增类
```java
package com.alibaba.nacos.plugin.datasource.enums;
import java.util.HashMap;
import java.util.Map;
public enum TrustedPostgreSqlFunctionEnum {
/**sange
* NOW().
*/
NOW("NOW()", "NOW()");
private static final Map LOOKUP_MAP = new HashMap<>();
static {
for (TrustedPostgreSqlFunctionEnum entry : TrustedPostgreSqlFunctionEnum.values()) {
LOOKUP_MAP.put(entry.functionName, entry);
}
}
private final String functionName;
private final String function;
TrustedPostgreSqlFunctionEnum(String functionName, String function) {
this.functionName = functionName;
this.function = function;
}
/**
* Get the function name.
*
* @param functionName function name
* @return function
*/
public static String getFunctionByName(String functionName) {
TrustedPostgreSqlFunctionEnum entry = LOOKUP_MAP.get(functionName);
if (entry != null) {
return entry.function;
}
throw new IllegalArgumentException(String.format("Invalid function name: %s", functionName));
}
}
```
修改类:
```java
/*
* Copyright 1999-2022 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.plugin.datasource.impl.postgresql;
import com.alibaba.nacos.plugin.datasource.constants.DatabaseTypeConstant;
import com.alibaba.nacos.plugin.datasource.enums.TrustedPostgreSqlFunctionEnum;
import com.alibaba.nacos.plugin.datasource.impl.base.BaseConfigInfoMapper;
/**
* The postgresql implementation of ConfigInfoMapper.
*
* @author Long Yu
**/
public class ConfigInfoMapperByPostgresql extends BaseConfigInfoMapper {
//这里是新增的
@Override
public String getFunction(String functionName)
{
return TrustedPostgreSqlFunctionEnum.getFunctionByName(functionName);
}
@Override
public String getDataSource() {
return DatabaseTypeConstant.POSTGRESQL;
}
}
```
编译打包好nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar
将此包上传到linux中
4.在linux中 安装V2.4.3版本的nacos docker镜像
地址:https://hub.docker.com/
>docker pull nacos/nacos-server:2.4.3
启动docker
>docker run -d
–name nacos
-e MODE=standalone
-p 8848:8848
-p 9848:9848
nacos/nacos-server:v2.4.3
>查看日志 docker logs -f nacos
启动正常以后,我们可以通过docker exec -it nacos /bin/bash 进入容器的/home/nacos中可以查看里面的目录信息
>copy 关键目录
接下来把data,logs,conf拷贝到宿主机上
cd 到mynacos目录下,执行
>docker cp nacos:/home/nacos/logs/ .
docker cp nacos:/home/nacos/data/ .
docker cp nacos:/home/nacos/conf/ .
这样就把nacos 的文件拷贝到本地了
4. 停止且删除容器
>docker rm -f nacos
5.重新启动nacos,并指定挂载目录
>docker run -d \
--name nacos \
-e MODE=standalone \
-p 8848:8848 \
-p 9848:9848 \
-v /xx/mynacos/logs/:/home/nacos/logs \
-v /xx/mynacos/conf/:/home/nacos/conf \
-v /xx/mynacos/data/:/home/nacos/data \
nacos/nacos-server:v2.4.3
docker run -itd --restart unless-stopped
增加这个参数可以让docker 挂了以后,自动重启
此时就要准备配置postgresql 的存储插件了
启动容器后,进入到容器中:
>docker exec -it nacos /bin/bash
> cd /home/nacos
> mkdir plugins
> exit
退出以后,在宿主机中,将宿主机中的插件拷贝到容器中
>dokcer cp /xx/mynacos/plugins/nacos-postgresql-datasource-plugin-ext-1.0.0-SNAPSHOT.jar nacos:/home/nacos/plugins
然后要修改启动的配置
>
>spring.datasource.platform=postgresql
db.num=1
db.url.0=jdbc:postgresql://localhost:5432/mydatabase?tcpKeepAlive=true&reWriteBatchedInserts=true&ApplicationName=nacos_java¤tSchema=nacos
db.user.0=用户名
db.password.0=密码
db.pool.config.driverClassName=org.postgresql.Driver
>
其中 currentSchema=nacos 是指定了schema
另外还可以打开鉴权:
nacos.core.auth.plugin.nacos.token.secret.key= 需要用base64加密一串长度不少于32位的字符串
我采用的是如下方式
```java
System.out.println("d166d71a-f8f2-49a0-a42a-9941f4914e26".length());;
String base64Str = Base64.getEncoder().encodeToString("d166d71a-f8f2-49a0-a42a-9941f4914e26".getBytes());
```
这里我是自定义了一样的值
nacos.core.auth.server.identity.key=xxx
nacos.core.auth.server.identity.value=xxx
nacos.core.auth.enabled=true
打开鉴权:
```shell
nacos.core.auth.plugin.nacos.token.expire.seconds=${NACOS_AUTH_TOKEN_EXPIRE_SECONDS:18000}
### The default token:
#nacos.core.auth.plugin.nacos.token.secret.key=${NACOS_AUTH_TOKEN:}
nacos.core.auth.plugin.nacos.token.secret.key=ZDE2NmQ3MWEtZjhmMi00OWEwLWE0MmEtOTk0MWY0OTE0ZTI2
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
nacos.core.auth.caching.enabled=${NACOS_AUTH_CACHE_ENABLE:false}
nacos.core.auth.enable.userAgentAuthWhite=${NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE:false}
#nacos.core.auth.server.identity.key=${NACOS_AUTH_IDENTITY_KEY:}
nacos.core.auth.server.identity.key=xxx
#nacos.core.auth.server.identity.value=${NACOS_AUTH_IDENTITY_VALUE:}
nacos.core.auth.server.identity.value=xxx
## spring security config
### turn off security
nacos.security.ignore.urls=${NACOS_SECURITY_IGNORE_URLS:/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**}
# metrics for elastic search
management.metrics.export.elastic.enabled=false
management.metrics.export.influx.enabled=false
nacos.naming.distro.taskDispatchThreadCount=10
nacos.naming.distro.taskDispatchPeriod=200
nacos.naming.distro.batchSyncKeyCount=1000
nacos.naming.distro.initDataRatio=0.9
nacos.naming.distro.syncRetryDelay=5000
nacos.naming.data.warmup=true
nacos.console.ui.enabled=true
nacos.core.param.check.enabled=true
#新加属性
nacos.core.auth.enabled=true
```
默认登录的账号密码对是nacos nacos
https://www.volcengine.com/docs/6738/1223801 ----配置文件加密
在java客户端,引入包:
对应的springboot版本是
```shell
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
```
```json
com.alibaba.boot
nacos-discovery-spring-boot-starter
0.2.10
com.alibaba.boot
nacos-config-spring-boot-starter
0.2.10
com.alibaba.boot
nacos-config-spring-boot-actuator
0.2.10
```
在application.yml中配置
```yaml
nacos:
config:
# bootstrap:
# enable: true
# log-enable: true
server-addr: localhost:8848
auto-fresh: true
remote-first: true
namespace: MYSPACE-${spring.profiles.active}
group: MYSPACE
enabled: true # false以后,本地nacos缓存依然有效,可能就不更新nacos最新配置了
file-extension: yaml # 只是针对默认和profile 的配置,定义的后缀
username: 用户名
password: 密码
```
```java
//自上而下加载,最好加载的会覆盖前面的配置
@SpringBootApplication
@NacosPropertySources({
@NacosPropertySource(type = ConfigType.YAML, dataId = "comm.yml",groupId = "MYSPACE",autoRefreshed = true, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME),
@NacosPropertySource(type = ConfigType.YAML, dataId = "application-${spring.profiles.active}.yml",groupId = "MYSPACE",autoRefreshed = true, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME),
@NacosPropertySource(type = ConfigType.YAML, dataId = "application-${spring.profiles.active}-nacos.yml",groupId = "MYSPACE",autoRefreshed = true, first = true, before = SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, after = SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)
})
@EnableNacosConfig
public class MyPlatformApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MyPlatformApplication.class, args);
}
}
```
这样在nacos服务控制台上,就可以配置MYSPACE-dev namespace
在此命名空间下,新建配置了
java端监听配置的变化
```java
@Component
public class EnvironmentListener {
@NacosConfigListener(dataId = "base.yml",groupId = "MYSPACE", type = ConfigType.YAML)
public void onChange(String content) {
System.out.println("receive config change event, content:" + content);
}
}
```
还可以额外监听某个配置文件的,某个prefix下的值
```java
@Configuration
@Data
@NacosConfigurationProperties(groupId = "MYSPACE",prefix = "filenacos.hadoop",dataId = "fileSystem-${spring.profiles.active}-nacos.yml",type = ConfigType.YAML, autoRefreshed = true)
public class NacosConfig {
//不加注解,如果nacos没有数据,则获取不到值;
// 如果@Value 所在的类上NacosConfigurationProperties,效果同NacosValue一样
// 如果单独使用@Value可以从nacos和本地获取,但是不会监测到nacos变更更新刷新数据
@Value("${filenacos.hadoop.basePath}")
private String basePath;
@Value("${filenacos.hadoop.clusterName}")
private String clusterName;
@Value("${filenacos.hadoop.clusterHostUrl}")
private String clusterHostUrl;
@Value("${filenacos.hadoop.authMode}")
private String authMode;
@Value("${filenacos.hadoop.csvFiles}")
private String csvFiles;
}
```
也可以在普通配置文件中,监听配置的变化
```java
@Configuration
@Data
public class BussinessConfig {
@NacosValue(value = "${ftp.newkey:default}",autoRefreshed = true)
private String ftpNewKey;
@NacosValue(value = "${mytest.newKey}",autoRefreshed = true)
private String newKey;
@Value("${mytest.freshkey1}")
private String freshkey1;
@NacosValue(value = "${mytest.freshkey2}",autoRefreshed = true)
private String freshkey2;
}
```
也可以通过API的方式获取数据变化
```java
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.Executor;
public class NacosTest {
private static final String NACOS_SERVER_ADDRESS = "http://localhost:8848";
private static final String NACOS_LOGIN_API ="/nacos/v1/auth/login";
private static final String USERNAME = "nacos";
private static final String PASSWORD = "nacos";
private static final String CONFIG_FETCH_API = "/nacos/v1/cs/configs?accessToken=${TOKEN}&dataId=${DATAID}&group=${GROUP}&tenant=${NAMESPACEID}";
public static void main(String[] args) throws IOException, InterruptedException {
monitor();
}
private static void loginAndFetchConfig(){
String token = getToken();
String config = fetchConfigValue(token,"base.yml","MYSPACE","MYSPACE-dev");
System.out.println(config);
}
private static String fetchConfigValue(String token,String dataId,String group,String namespaceId){
RestTemplate restTemplate = new RestTemplate();
String url = StringUtils.replace(NACOS_SERVER_ADDRESS + CONFIG_FETCH_API,"${TOKEN}",token)
.replace("${DATAID}",dataId)
.replace("${GROUP}",group)
.replace("${NAMESPACEID}",namespaceId);
ResponseEntity response = restTemplate.getForEntity(url, String.class);
if (response.getStatusCode().is2xxSuccessful()) {
return response.getBody();
}
return "Failed to get config from Nacos";
}
private static String getToken() {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap map = new LinkedMultiValueMap<>();
map.add("username", USERNAME);
map.add("password", PASSWORD);
HttpEntity> requestEntity = new HttpEntity<>(map, headers);
ResponseEntity response = restTemplate.postForEntity(NACOS_SERVER_ADDRESS + NACOS_LOGIN_API, requestEntity, String.class);
String responseBody = response.getBody();
if(StringUtils.isNotBlank(responseBody) && responseBody.contains("accessToken")){
return JSONObject.parseObject(responseBody).getString("accessToken");
}
return null;
}
private static void monitor(){
try {
String serverAddr = "localhost:8848";
String dataId = "base.yml";
String group = "MYSPACE";
Properties properties = new Properties();
properties.put("serverAddr", serverAddr);
properties.put("username","nacos");
properties.put("password","nacos");
properties.put("namespace","MYSPACE-dev");
ConfigService configService = NacosFactory.createConfigService(properties);
String content = configService.getConfigAndSignListener(dataId, group, 5000, new Listener() {
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("recieve1:" + configInfo);
}
@Override
public Executor getExecutor() {
return null;
}
});
System.out.println(content);
} catch (NacosException e) {
e.printStackTrace();
}
}
}
```