Skip to content

Commit ab5b303

Browse files
[ISSUE alibaba#12017] Fix backend bugs
* Modified the namespace update method * Added two beta-related API in the config section * Modified relevant unit tests
1 parent 4fc7ec2 commit ab5b303

File tree

8 files changed

+205
-15
lines changed

8 files changed

+205
-15
lines changed

console/src/main/java/com/alibaba/nacos/console/controller/v3/config/ConsoleConfigController.java

+48-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
2929
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
3030
import com.alibaba.nacos.config.server.model.ConfigInfo;
31+
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
3132
import com.alibaba.nacos.config.server.model.ConfigRequestInfo;
3233
import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus;
3334
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
@@ -41,6 +42,7 @@
4142
import com.alibaba.nacos.persistence.model.Page;
4243
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
4344
import com.alibaba.nacos.plugin.auth.constant.SignType;
45+
import org.springframework.http.HttpStatus;
4446
import org.springframework.http.ResponseEntity;
4547
import org.springframework.ui.ModelMap;
4648
import org.springframework.web.bind.annotation.DeleteMapping;
@@ -60,6 +62,8 @@
6062
import java.util.List;
6163
import java.util.Map;
6264

65+
import static com.alibaba.nacos.config.server.utils.RequestUtil.getRemoteIp;
66+
6367
/**
6468
* Controller for handling HTTP requests related to configuration operations.
6569
*
@@ -74,7 +78,6 @@ public class ConsoleConfigController {
7478

7579
public ConsoleConfigController(ConfigProxy configProxy) {
7680
this.configProxy = configProxy;
77-
7881
}
7982

8083
/**
@@ -401,15 +404,11 @@ public Result<Map<String, Object>> importAndPublishConfig(HttpServletRequest req
401404
@Secured(action = ActionTypes.WRITE, signType = SignType.CONFIG, apiType = ApiType.CONSOLE_API)
402405
public Result<Map<String, Object>> cloneConfig(HttpServletRequest request,
403406
@RequestParam(value = "src_user", required = false) String srcUser,
404-
@RequestParam(value = "namespaceId") String namespaceId,
407+
@RequestParam(value = "targetNamespaceId") String namespaceId,
405408
@RequestBody List<SameNamespaceCloneConfigBean> configBeansList,
406409
@RequestParam(value = "policy", defaultValue = "ABORT") SameConfigPolicy policy) throws NacosException {
407-
408410
configBeansList.removeAll(Collections.singleton(null));
409-
// check namespaceId
410-
ParamUtils.checkTenantV2(namespaceId);
411411
namespaceId = NamespaceUtil.processNamespaceParameter(namespaceId);
412-
413412
if (StringUtils.isBlank(srcUser)) {
414413
srcUser = RequestUtil.getSrcUserName(request);
415414
}
@@ -419,6 +418,49 @@ public Result<Map<String, Object>> cloneConfig(HttpServletRequest request,
419418
return configProxy.cloneConfig(srcUser, namespaceId, configBeansList, policy, srcIp, requestIpApp);
420419
}
421420

421+
/**
422+
* Execute to remove beta operation.
423+
*
424+
* @param httpServletRequest HTTP request containing client details.
425+
* @param dataId dataId string value.
426+
* @param group group string value.
427+
* @param namespaceId tenant string value.
428+
* @return Result indicating the outcome of the operation.
429+
* @throws NacosException If a Nacos-specific error occurs.
430+
*/
431+
@DeleteMapping("/beta")
432+
@Secured(action = ActionTypes.WRITE, signType = SignType.CONFIG)
433+
public Result<Boolean> stopBeta(HttpServletRequest httpServletRequest,
434+
@RequestParam(value = "dataId") String dataId, @RequestParam(value = "group") String group,
435+
@RequestParam(value = "namespaceId", required = false, defaultValue = StringUtils.EMPTY) String namespaceId)
436+
throws NacosException {
437+
String remoteIp = getRemoteIp(httpServletRequest);
438+
String requestIpApp = RequestUtil.getAppName(httpServletRequest);
439+
boolean success = configProxy.removeBetaConfig(dataId, group, namespaceId, remoteIp, requestIpApp);
440+
if (!success) {
441+
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), false);
442+
}
443+
return Result.success(true);
444+
}
445+
446+
/**
447+
* Execute to query beta operation.
448+
*
449+
* @param dataId dataId string value.
450+
* @param group group string value.
451+
* @param namespaceId namespaceId string value.
452+
* @return Result containing the ConfigInfo4Beta details.
453+
* @throws NacosException If a Nacos-specific error occurs.
454+
*/
455+
@GetMapping("/beta")
456+
@Secured(action = ActionTypes.READ, signType = SignType.CONFIG)
457+
public Result<ConfigInfo4Beta> queryBeta(@RequestParam(value = "dataId") String dataId,
458+
@RequestParam(value = "group") String group,
459+
@RequestParam(value = "namespaceId", required = false, defaultValue = StringUtils.EMPTY) String namespaceId)
460+
throws NacosException {
461+
return configProxy.queryBetaConfig(dataId, group, namespaceId);
462+
}
463+
422464
}
423465

424466

console/src/main/java/com/alibaba/nacos/console/controller/v3/core/ConsoleNamespaceController.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ public Result<Namespace> getNamespaceDetail(@RequestParam("namespaceId") String
9696

9797
/**
9898
* create namespace.
99-
* @param namespaceId custom namespace id
99+
*
100+
* @param namespaceId custom namespace id
100101
* @param namespaceName custom namespace name
101102
* @param namespaceDesc custom namespace description
102103
* @return whether create ok
@@ -137,13 +138,21 @@ public Result<Boolean> createNamespace(@RequestParam("customNamespaceId") String
137138
/**
138139
* edit namespace.
139140
*
140-
* @param namespaceForm namespace params
141+
* @param namespaceId the ID of the namespace
142+
* @param namespaceName the new name of the namespace
143+
* @param namespaceDesc optional description of the namespace
141144
* @return whether edit ok
142145
*/
143146
@PutMapping
144147
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
145148
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE, apiType = ApiType.CONSOLE_API)
146-
public Result<Boolean> updateNamespace(NamespaceForm namespaceForm) throws NacosException {
149+
public Result<Boolean> updateNamespace(@RequestParam("customNamespaceId") String namespaceId,
150+
@RequestParam("namespaceName") String namespaceName,
151+
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) throws NacosException {
152+
NamespaceForm namespaceForm = new NamespaceForm();
153+
namespaceForm.setNamespaceId(namespaceId);
154+
namespaceForm.setNamespaceName(namespaceName);
155+
namespaceForm.setNamespaceDesc(namespaceDesc);
147156
namespaceForm.validate();
148157
// contains illegal chars
149158
if (!namespaceNameCheckPattern.matcher(namespaceForm.getNamespaceName()).matches()) {

console/src/main/java/com/alibaba/nacos/console/controller/v3/naming/ConsoleServiceController.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package com.alibaba.nacos.console.controller.v3.naming;
1919

20+
import com.alibaba.nacos.api.annotation.NacosApi;
2021
import com.alibaba.nacos.api.common.Constants;
2122
import com.alibaba.nacos.api.exception.NacosException;
2223
import com.alibaba.nacos.api.exception.api.NacosApiException;
@@ -68,6 +69,7 @@
6869
*
6970
* @author zhangyukun on:2024/8/16
7071
*/
72+
@NacosApi
7173
@RestController
7274
@RequestMapping("/v3/console/ns/service")
7375
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)

console/src/main/java/com/alibaba/nacos/console/handler/config/ConfigHandler.java

+23
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
2323
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
2424
import com.alibaba.nacos.config.server.model.ConfigInfo;
25+
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
2526
import com.alibaba.nacos.config.server.model.ConfigRequestInfo;
2627
import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus;
2728
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
@@ -204,4 +205,26 @@ Result<Map<String, Object>> importAndPublishConfig(String srcUser, String namesp
204205
Result<Map<String, Object>> cloneConfig(String srcUser, String namespaceId,
205206
List<SameNamespaceCloneConfigBean> configBeansList, SameConfigPolicy policy, String srcIp,
206207
String requestIpApp) throws NacosException;
208+
209+
/**
210+
* Remove beta configuration based on dataId, group, and namespaceId.
211+
*
212+
* @param dataId the dataId
213+
* @param group the group
214+
* @param namespaceId the namespaceId
215+
* @param remoteIp the IP address of the client making the request
216+
* @param requestIpApp the name of the application making the request
217+
* @return true if the beta configuration is successfully removed
218+
*/
219+
boolean removeBetaConfig(String dataId, String group, String namespaceId, String remoteIp, String requestIpApp);
220+
221+
/**
222+
* Query beta configuration based on dataId, group, and namespaceId.
223+
*
224+
* @param dataId the dataId
225+
* @param group the group
226+
* @param namespaceId the namespaceId
227+
* @return ConfigInfo4Beta containing the beta configuration details
228+
*/
229+
Result<ConfigInfo4Beta> queryBetaConfig(String dataId, String group, String namespaceId);
207230
}

console/src/main/java/com/alibaba/nacos/console/handler/inner/config/ConfigInnerHandler.java

+42-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
2929
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
3030
import com.alibaba.nacos.config.server.model.ConfigInfo;
31+
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
3132
import com.alibaba.nacos.config.server.model.ConfigMetadata;
3233
import com.alibaba.nacos.config.server.model.ConfigRequestInfo;
3334
import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus;
@@ -39,6 +40,7 @@
3940
import com.alibaba.nacos.config.server.service.ConfigDetailService;
4041
import com.alibaba.nacos.config.server.service.ConfigOperationService;
4142
import com.alibaba.nacos.config.server.service.ConfigSubService;
43+
import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService;
4244
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
4345
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
4446
import com.alibaba.nacos.config.server.utils.GroupKey;
@@ -101,15 +103,19 @@ public class ConfigInnerHandler implements ConfigHandler {
101103

102104
private NamespacePersistService namespacePersistService;
103105

106+
private ConfigInfoBetaPersistService configInfoBetaPersistService;
107+
104108
public ConfigInnerHandler(ConfigServletInner inner, ConfigOperationService configOperationService,
105109
ConfigInfoPersistService configInfoPersistService, ConfigDetailService configDetailService,
106-
ConfigSubService configSubService, NamespacePersistService namespacePersistService) {
110+
ConfigSubService configSubService, NamespacePersistService namespacePersistService,
111+
ConfigInfoBetaPersistService configInfoBetaPersistService) {
107112
this.inner = inner;
108113
this.configOperationService = configOperationService;
109114
this.configInfoPersistService = configInfoPersistService;
110115
this.configDetailService = configDetailService;
111116
this.configSubService = configSubService;
112117
this.namespacePersistService = namespacePersistService;
118+
this.configInfoBetaPersistService = configInfoBetaPersistService;
113119
}
114120

115121
@Override
@@ -582,4 +588,39 @@ public Result<Map<String, Object>> cloneConfig(String srcUser, String namespaceI
582588
return Result.success(saveResult);
583589
}
584590

591+
@Override
592+
public boolean removeBetaConfig(String dataId, String group, String namespaceId, String remoteIp,
593+
String requestIpApp) {
594+
try {
595+
configInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, namespaceId);
596+
} catch (Throwable e) {
597+
LOGGER.error("remove beta data error", e);
598+
return false;
599+
}
600+
ConfigTraceService.logPersistenceEvent(dataId, group, namespaceId, requestIpApp, System.currentTimeMillis(),
601+
remoteIp, ConfigTraceService.PERSISTENCE_EVENT_BETA, ConfigTraceService.PERSISTENCE_TYPE_REMOVE, null);
602+
ConfigChangePublisher.notifyConfigChange(
603+
new ConfigDataChangeEvent(true, dataId, group, namespaceId, System.currentTimeMillis()));
604+
return true;
605+
606+
}
607+
608+
@Override
609+
public Result<ConfigInfo4Beta> queryBetaConfig(String dataId, String group, String namespaceId) {
610+
try {
611+
ConfigInfo4Beta ci = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, namespaceId);
612+
613+
if (Objects.nonNull(ci)) {
614+
String encryptedDataKey = ci.getEncryptedDataKey();
615+
Pair<String, String> pair = EncryptionHandler.decryptHandler(dataId, encryptedDataKey, ci.getContent());
616+
ci.setContent(pair.getSecond());
617+
}
618+
return Result.success(ci);
619+
} catch (Throwable e) {
620+
LOGGER.error("query beta data error", e);
621+
return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(),
622+
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), null);
623+
}
624+
}
625+
585626
}

console/src/main/java/com/alibaba/nacos/console/proxy/config/ConfigProxy.java

+24
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
2323
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
2424
import com.alibaba.nacos.config.server.model.ConfigInfo;
25+
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
2526
import com.alibaba.nacos.config.server.model.ConfigRequestInfo;
2627
import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus;
2728
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
@@ -200,4 +201,27 @@ public Result<Map<String, Object>> cloneConfig(String srcUser, String namespaceI
200201
}
201202
return configHandler.cloneConfig(srcUser, namespaceId, configBeansList, policy, srcIp, requestIpApp);
202203
}
204+
205+
/**
206+
* Remove beta configuration based on dataId, group, and namespaceId.
207+
*/
208+
public boolean removeBetaConfig(String dataId, String group, String namespaceId, String remoteIp,
209+
String requestIpApp) throws NacosException {
210+
ConfigHandler configHandler = configHandlerMap.get(consoleConfig.getType());
211+
if (configHandler == null) {
212+
throw new NacosException(NacosException.INVALID_PARAM, "Invalid deployment type");
213+
}
214+
return configHandler.removeBetaConfig(dataId, group, namespaceId, remoteIp, requestIpApp);
215+
}
216+
217+
/**
218+
* Query beta configuration based on dataId, group, and namespaceId.
219+
*/
220+
public Result<ConfigInfo4Beta> queryBetaConfig(String dataId, String group, String namespaceId) throws NacosException {
221+
ConfigHandler configHandler = configHandlerMap.get(consoleConfig.getType());
222+
if (configHandler == null) {
223+
throw new NacosException(NacosException.INVALID_PARAM, "Invalid deployment type");
224+
}
225+
return configHandler.queryBetaConfig(dataId, group, namespaceId);
226+
}
203227
}

console/src/test/java/com/alibaba/nacos/console/controller/v3/config/ConsoleConfigControllerTest.java

+50
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.alibaba.nacos.config.server.controller.parameters.SameNamespaceCloneConfigBean;
2626
import com.alibaba.nacos.config.server.model.ConfigAllInfo;
2727
import com.alibaba.nacos.config.server.model.ConfigInfo;
28+
import com.alibaba.nacos.config.server.model.ConfigInfo4Beta;
2829
import com.alibaba.nacos.config.server.model.ConfigRequestInfo;
2930
import com.alibaba.nacos.config.server.model.SameConfigPolicy;
3031
import com.alibaba.nacos.config.server.model.form.ConfigForm;
@@ -67,6 +68,7 @@
6768
import static org.junit.jupiter.api.Assertions.assertEquals;
6869
import static org.junit.jupiter.api.Assertions.assertTrue;
6970
import static org.mockito.ArgumentMatchers.any;
71+
import static org.mockito.ArgumentMatchers.anyString;
7072
import static org.mockito.ArgumentMatchers.argThat;
7173
import static org.mockito.ArgumentMatchers.eq;
7274
import static org.mockito.Mockito.verify;
@@ -427,4 +429,52 @@ public boolean matches(List<SameNamespaceCloneConfigBean> argument) {
427429
}
428430
}), eq(SameConfigPolicy.ABORT), eq("127.0.0.1"), eq(null));
429431
}
432+
433+
@Test
434+
void testStopBeta() throws Exception {
435+
// Mock configuration
436+
String dataId = "testDataId";
437+
String group = "testGroup";
438+
String namespaceId = "testNamespaceId";
439+
when(configProxy.removeBetaConfig(anyString(), anyString(), anyString(), anyString(), anyString())).thenReturn(
440+
true);
441+
442+
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete("/v3/console/cs/config/beta")
443+
.param("dataId", dataId).param("group", group).param("namespaceId", namespaceId);
444+
445+
// Execute and validate response
446+
MockHttpServletResponse response = mockmvc.perform(builder).andReturn().getResponse();
447+
String actualValue = response.getContentAsString();
448+
449+
Result<Boolean> result = new ObjectMapper().readValue(actualValue, new TypeReference<Result<Boolean>>() {
450+
});
451+
452+
assertEquals(200, response.getStatus());
453+
}
454+
455+
@Test
456+
void testQueryBetaSuccess() throws Exception {
457+
// Mock configuration for successful response
458+
String dataId = "testDataId";
459+
String group = "testGroup";
460+
461+
ConfigInfo4Beta mockConfigInfo = new ConfigInfo4Beta();
462+
mockConfigInfo.setDataId(dataId);
463+
mockConfigInfo.setGroup(group);
464+
Result<ConfigInfo4Beta> mockResult = new Result<>();
465+
when(configProxy.queryBetaConfig(anyString(), anyString(), anyString())).thenReturn(mockResult);
466+
String namespaceId = "testNamespaceId";
467+
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/v3/console/cs/config/beta")
468+
.param("dataId", dataId).param("group", group).param("namespaceId", namespaceId);
469+
470+
// Execute and validate response
471+
MockHttpServletResponse response = mockmvc.perform(builder).andReturn().getResponse();
472+
String actualValue = response.getContentAsString();
473+
474+
Result<ConfigInfo4Beta> result = new ObjectMapper().readValue(actualValue,
475+
new TypeReference<Result<ConfigInfo4Beta>>() {
476+
});
477+
478+
assertEquals(200, response.getStatus());
479+
}
430480
}

console/src/test/java/com/alibaba/nacos/console/controller/v3/core/ConsoleNamespaceControllerTest.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,15 @@ void testGetNamespaceDetail() throws Exception {
112112

113113
@Test
114114
void testUpdateNamespace() throws Exception {
115-
NamespaceForm namespaceForm = new NamespaceForm();
116-
namespaceForm.setNamespaceId("testNamespace");
117-
namespaceForm.setNamespaceName("testNamespaceName");
118-
namespaceForm.setNamespaceDesc("testDesc");
115+
String namespaceId = "testNamespace";
116+
String namespaceName = "testNamespaceName";
117+
String namespaceDesc = "testDesc";
119118

120119
MockHttpServletRequest request = new MockHttpServletRequest();
121120

122121
when(namespaceProxy.updateNamespace(any(NamespaceForm.class))).thenReturn(true);
123122

124-
Result<Boolean> result = consoleNamespaceController.updateNamespace(namespaceForm);
123+
Result<Boolean> result = consoleNamespaceController.updateNamespace(namespaceId, namespaceName, namespaceDesc);
125124

126125
verify(namespaceProxy).updateNamespace(any(NamespaceForm.class));
127126

0 commit comments

Comments
 (0)