Skip to content

Commit

Permalink
[ISSUE #12017] Refactor the old version of the console's controller (#…
Browse files Browse the repository at this point in the history
…12591)

* Refactor the old version of the console's controller
  • Loading branch information
RickonZhang0929 authored Sep 4, 2024
1 parent f1b00a3 commit a890d0d
Show file tree
Hide file tree
Showing 12 changed files with 952 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 1999-2024 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.console.controller.v3;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.console.proxy.HealthProxy;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
* Controller class for handling health check operations.
*
* @author zhangyukun on:2024/8/27
*/
@RestController()
@RequestMapping("/v3/console/health")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class ConsoleHealthController {

private final HealthProxy healthProxy;

public ConsoleHealthController(HealthProxy healthProxy) {
this.healthProxy = healthProxy;
}

/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted.
*
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
@GetMapping("/liveness")
public Result<String> liveness() {
return Result.success("ok");
}

/**
* Ready to receive the request or not.
*
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready.
*/
@GetMapping("/readiness")
public Result<String> readiness(HttpServletRequest request) throws NacosException {
return healthProxy.checkReadiness();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 1999-2024 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.console.controller.v3;

import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.console.proxy.ServerStateProxy;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
* Controller for managing server state-related operations.
*
* @author zhangyukun on:2024/8/27
*/
@RestController
@RequestMapping("/v3/console/server")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class ConsoleServerStateController {

private final ServerStateProxy serverStateProxy;

public ConsoleServerStateController(ServerStateProxy serverStateProxy) {
this.serverStateProxy = serverStateProxy;
}

/**
* Get server state of current server.
*
* @return state json.
*/
@GetMapping("/state")
public Result<Map<String, String>> serverState() {
Map<String, String> serverState = serverStateProxy.getServerState();
return Result.success(serverState);
}

/**
* Get the announcement content based on the specified language.
*
* @param language Language for the announcement (default: "zh-CN")
* @return Announcement content as a string wrapped in a Result object
*/
@GetMapping("/announcement")
public Result<String> getAnnouncement(
@RequestParam(required = false, name = "language", defaultValue = "zh-CN") String language) {
String announcement = serverStateProxy.getAnnouncement(language);
return Result.success(announcement);
}

/**
* Get the console UI guide information.
*
* @return Console UI guide information as a string wrapped in a Result object
*/
@GetMapping("/guide")
public Result<String> getConsoleUiGuide() {
String guideInformation = serverStateProxy.getConsoleUiGuide();
return Result.success(guideInformation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* Copyright 1999-2024 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.console.controller.v3.core;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.api.NacosApiException;
import com.alibaba.nacos.api.model.v2.ErrorCode;
import com.alibaba.nacos.api.model.v2.Result;
import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.console.paramcheck.ConsoleDefaultHttpParamExtractor;
import com.alibaba.nacos.console.proxy.core.NamespaceProxy;
import com.alibaba.nacos.core.namespace.model.Namespace;
import com.alibaba.nacos.core.namespace.model.form.NamespaceForm;
import com.alibaba.nacos.core.namespace.repository.NamespacePersistService;
import com.alibaba.nacos.core.paramcheck.ExtractorManager;
import com.alibaba.nacos.plugin.auth.constant.ActionTypes;
import com.alibaba.nacos.plugin.auth.constant.SignType;
import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

/**
* Controller for handling HTTP requests related to namespace operations.
*
* @author zhangyukun on:2024/8/27
*/
@RestController
@RequestMapping("/v3/console/namespace")
@ExtractorManager.Extractor(httpExtractor = ConsoleDefaultHttpParamExtractor.class)
public class ConsoleNamespaceController {

private final NamespaceProxy namespaceProxy;

private final NamespacePersistService namespacePersistService;

public ConsoleNamespaceController(NamespaceProxy namespaceProxy, NamespacePersistService namespacePersistService) {
this.namespaceProxy = namespaceProxy;
this.namespacePersistService = namespacePersistService;
}

private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");

private final Pattern namespaceNameCheckPattern = Pattern.compile("^[^@#$%^&*]+$");

private static final int NAMESPACE_ID_MAX_LENGTH = 128;

/**
* Get namespace list.
*
* @return namespace list
*/
@GetMapping("/list")
public Result<List<Namespace>> getNamespaceList() throws NacosException {
return Result.success(namespaceProxy.getNamespaceList());
}

/**
* get namespace all info by namespace id.
*
* @param namespaceId namespaceId
* @return namespace all info
*/
@GetMapping()
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.READ, signType = SignType.CONSOLE)
public Result<Namespace> getNamespaceDetail(@RequestParam("namespaceId") String namespaceId) throws NacosException {
return Result.success(namespaceProxy.getNamespaceDetail(namespaceId));
}

/**
* create namespace.
*
* @param namespaceForm namespaceForm.
* @return whether create ok
*/
@PostMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> createNamespace(NamespaceForm namespaceForm) throws NacosException {

namespaceForm.validate();

String namespaceId = namespaceForm.getNamespaceId();
String namespaceName = namespaceForm.getNamespaceName();
String namespaceDesc = namespaceForm.getNamespaceDesc();

if (StringUtils.isBlank(namespaceId)) {
namespaceId = UUID.randomUUID().toString();
} else {
namespaceId = namespaceId.trim();
if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceId [" + namespaceId + "] mismatch the pattern");
}
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"too long namespaceId, over " + NAMESPACE_ID_MAX_LENGTH);
}
// check unique
if (namespacePersistService.tenantInfoCountByTenantId(namespaceId) > 0) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"the namespaceId is existed, namespaceId: " + namespaceForm.getNamespaceId());
}
}
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceName).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceName [" + namespaceName + "] contains illegal char");
}
return Result.success(namespaceProxy.createNamespace(namespaceId, namespaceName, namespaceDesc));
}

/**
* edit namespace.
*
* @param namespaceForm namespace params
* @return whether edit ok
*/
@PutMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> updateNamespace(NamespaceForm namespaceForm) throws NacosException {
namespaceForm.validate();
// contains illegal chars
if (!namespaceNameCheckPattern.matcher(namespaceForm.getNamespaceName()).matches()) {
throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.ILLEGAL_NAMESPACE,
"namespaceName [" + namespaceForm.getNamespaceName() + "] contains illegal char");
}
return Result.success(namespaceProxy.updateNamespace(namespaceForm));
}

/**
* delete namespace by id.
*
* @param namespaceId namespace ID
* @return whether delete ok
*/
@DeleteMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX
+ "namespaces", action = ActionTypes.WRITE, signType = SignType.CONSOLE)
public Result<Boolean> deleteNamespace(@RequestParam("namespaceId") String namespaceId) throws NacosException {
return Result.success(namespaceProxy.deleteNamespace(namespaceId));
}

/**
* check namespaceId exist.
*
* @param namespaceId namespace id
* @return true if exist, otherwise false
*/
@GetMapping("/exist")
public Result<Boolean> checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId)
throws NacosException {
if (StringUtils.isBlank(namespaceId)) {
return Result.success(false);
}
return Result.success(namespaceProxy.checkNamespaceIdExist(namespaceId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 1999-2024 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.console.handler;

import com.alibaba.nacos.api.model.v2.Result;

/**
* Interface for handling health check operations.
*
* @author zhangyukun
*/
public interface HealthHandler {

/**
* Perform readiness check to determine if Nacos is ready to handle requests.
*
* @return readiness result
*/
Result<String> checkReadiness();
}

Loading

0 comments on commit a890d0d

Please sign in to comment.