Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to delete AppNamespace #4499

Merged
merged 68 commits into from
Aug 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
fe75b4d
add tech-support-qq-4.png
klboke May 16, 2019
99bf97a
Update README.md
klboke May 16, 2019
1579f41
Merge remote-tracking branch 'upstream/master'
klboke Nov 11, 2020
9f65eed
Merge remote-tracking branch 'upstream/master'
klboke Dec 9, 2020
d7d3fd9
Enhance the user experience in the scenario of submitting duplicate keys
klboke Dec 11, 2020
7329fab
Merge branch 'master' into master
nobodyiam Dec 12, 2020
5def448
Modify the key-value conflict exception prompt, adjust the code style
klboke Dec 12, 2020
6942564
Merge branch 'master' into master
nobodyiam Dec 12, 2020
0fc1f91
Merge remote-tracking branch 'upstream/master'
klboke Dec 19, 2020
61ad016
Merge remote-tracking branch 'origin/master'
klboke Dec 19, 2020
587ce33
rge remote-tracking branch 'upstream/master'
klboke Mar 1, 2021
9de6563
Merge remote-tracking branch 'upstream/master'
klboke Mar 8, 2021
9aab632
Merge remote-tracking branch 'upstream/master'
klboke Mar 25, 2021
050dd0a
Merge branch 'ctripcorp:master' into master
klboke May 10, 2021
5a64035
Merge branch 'master' of github.com:klboke/apollo
klboke May 10, 2021
0648fbd
Merge branch 'ctripcorp:master' into master
klboke May 19, 2021
35bd3a6
Merge branch 'master' of github.com:klboke/apollo
klboke May 19, 2021
bc8149b
Merge branch 'ctripcorp:master' into master
klboke Jun 8, 2021
e771bdd
Merge branch 'master' of github.com:klboke/apollo
klboke Jun 8, 2021
9a1ad83
Merge branch 'ctripcorp:master' into master
klboke Jun 25, 2021
3efef37
Merge branch 'master' of github.com:klboke/apollo
klboke Jun 25, 2021
1274281
Merge branch 'apolloconfig:master' into master
klboke Sep 1, 2021
a968932
Merge branch 'master' of github.com:klboke/apollo
klboke Sep 1, 2021
df8942c
Merge branch 'apolloconfig:master' into master
klboke Jan 7, 2022
f98175a
Merge branch 'master' of github.com:klboke/apollo
klboke Jan 7, 2022
710cdd6
Merge branch 'apolloconfig:master' into master
klboke Feb 18, 2022
3c162b6
Merge branch 'master' of github.com:klboke/apollo
klboke Feb 18, 2022
0101a3f
Merge branch 'apolloconfig:master' into master
klboke Jun 17, 2022
cc6f568
Merge branch 'master' of github.com:klboke/apollo
klboke Jun 17, 2022
21dd30c
Merge branch 'apolloconfig:master' into master
klboke Jun 21, 2022
c1eeb41
Merge branch 'master' of github.com:klboke/apollo
klboke Jun 21, 2022
e85d645
Merge branch 'apolloconfig:master' into master
klboke Jun 27, 2022
8b0056d
Merge branch 'master' of github.com:klboke/apollo
klboke Jun 27, 2022
347e07b
Merge branch 'apolloconfig:master' into master
klboke Jul 1, 2022
d8eb437
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 1, 2022
19bae52
Merge branch 'apolloconfig:master' into master
klboke Jul 4, 2022
7e40fa1
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 4, 2022
fbbb02d
Merge branch 'apolloconfig:master' into master
klboke Jul 6, 2022
19cee24
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 6, 2022
91ba3b7
Merge branch 'apolloconfig:master' into master
klboke Jul 8, 2022
94ad542
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 8, 2022
64e1b0b
Merge branch 'apolloconfig:master' into master
klboke Jul 19, 2022
36ce5e2
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 19, 2022
c1364c2
Merge branch 'apolloconfig:master' into master
klboke Jul 22, 2022
76ed2ea
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 22, 2022
db8cf3d
Merge branch 'apolloconfig:master' into master
klboke Jul 26, 2022
3e4616d
Merge branch 'master' of github.com:klboke/apollo
klboke Jul 26, 2022
47297cc
Merge branch 'apolloconfig:master' into master
klboke Jul 30, 2022
1c320e7
Merge branch 'apolloconfig:master' into master
klboke Aug 2, 2022
e723db5
Merge branch 'master' of github.com:klboke/apollo
klboke Aug 2, 2022
df1dc49
refactor(apollo-portal): Allow users to delete AppNamespace(https://g…
klboke Aug 3, 2022
ef6325d
doc(CHANGES.md): update CHANGES.md
klboke Aug 3, 2022
f4c6881
Update apollo-portal/src/main/resources/static/i18n/en.json
klboke Aug 4, 2022
fae7f9f
Update apollo-portal/src/main/resources/static/i18n/zh-CN.json
klboke Aug 4, 2022
1be9790
Update apollo-portal/src/main/resources/static/i18n/zh-CN.json
klboke Aug 4, 2022
9dcc111
Merge branch 'master' into deleted-namespace
klboke Aug 9, 2022
d388f0e
feat(apollo-portal): Delete Namespace
klboke Aug 11, 2022
66ee7d6
Update apollo-portal/src/main/resources/static/i18n/en.json
klboke Aug 12, 2022
ecd91bc
Update apollo-portal/src/main/resources/static/i18n/en.json
klboke Aug 12, 2022
197b684
Update apollo-portal/src/main/resources/static/scripts/directive/dele…
klboke Aug 12, 2022
b0a5f45
Update apollo-portal/src/main/resources/static/scripts/directive/dele…
klboke Aug 12, 2022
4ec7117
Update apollo-portal/src/main/resources/static/scripts/directive/dele…
klboke Aug 12, 2022
19d8940
Update apollo-portal/src/main/resources/static/scripts/directive/dele…
klboke Aug 12, 2022
2c942f4
Update apollo-portal/src/main/resources/static/scripts/directive/dele…
klboke Aug 12, 2022
454488d
Update apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/…
klboke Aug 12, 2022
6c57b80
Update apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/…
klboke Aug 12, 2022
cb14888
feat(apollo-portal): Remove server-side delete Namespace check
klboke Aug 12, 2022
4696f13
Fix(apollo-portal): Fix NamespaceServiceTest test case
klboke Aug 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Apollo 2.1.0
* [fix(#4474):'openjdk:8-jre-alpine' potentially causing wrong number of cpu cores](https://github.com/apolloconfig/apollo/pull/4475)
* [Switching spring-session serialization mode to json for compatibility with spring-security version updates]()
* [fix(#4483):Fixed overwrite JSON type configuration being empty](https://github.com/apolloconfig/apollo/pull/4486)
* [Allow users to delete AppNamespace](https://github.com/apolloconfig/apollo/pull/4499)
* [fix the deleted at timestamp issue](https://github.com/apolloconfig/apollo/pull/4493)

------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.ctrip.framework.apollo.common.utils.BeanUtils;
import com.ctrip.framework.apollo.common.utils.InputValidator;
import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceUsage;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.component.PermissionValidator;
Expand All @@ -38,6 +39,7 @@
import com.ctrip.framework.apollo.portal.service.RoleInitializationService;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -168,16 +170,28 @@ public ResponseEntity<Void> createNamespace(@PathVariable String appId,
}

@PreAuthorize(value = "@permissionValidator.hasDeleteNamespacePermission(#appId)")
@DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName:.+}")
public ResponseEntity<Void> deleteNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName) {
@DeleteMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/linked-namespaces/{namespaceName:.+}")
public ResponseEntity<Void> deleteLinkedNamespace(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName) {

namespaceService.deleteNamespace(appId, Env.valueOf(env), clusterName, namespaceName);

return ResponseEntity.ok().build();
}

@PreAuthorize(value = "@permissionValidator.isSuperAdmin()")
@GetMapping("/apps/{appId}/envs/{env}/clusters/{clusterName}/linked-namespaces/{namespaceName}/usage")
public List<NamespaceUsage> findLinkedNamespaceUsage(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName) {
NamespaceUsage usage = namespaceService.getNamespaceUsageByEnv(appId, namespaceName, Env.valueOf(env), clusterName);
return Lists.newArrayList(usage);
}

@GetMapping("/apps/{appId}/namespaces/{namespaceName}/usage")
public List<NamespaceUsage> findNamespaceUsage(@PathVariable String appId, @PathVariable String namespaceName) {
return namespaceService.getNamespaceUsageByAppId(appId, namespaceName);
}

@PreAuthorize(value = "@permissionValidator.hasDeleteNamespacePermission(#appId)")
@DeleteMapping("/apps/{appId}/appnamespaces/{namespaceName:.+}")
public ResponseEntity<Void> deleteAppNamespace(@PathVariable String appId, @PathVariable String namespaceName) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2022 Apollo Authors
*
* 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.ctrip.framework.apollo.portal.entity.vo;

/**
* @author kl (http://kailing.pub)
* @since 2022/8/9
*/
public class NamespaceUsage {

private String namespaceName;
private String appId;
private String clusterName;
private String envName;
private int instanceCount;
private int branchInstanceCount;
private int linkedNamespaceCount;


public NamespaceUsage() {
}

public NamespaceUsage(String namespaceName, String appId, String clusterName,
String envName) {
this.namespaceName = namespaceName;
this.appId = appId;
this.clusterName = clusterName;
this.envName = envName;
}

public String getNamespaceName() {
return namespaceName;
}

public void setNamespaceName(String namespaceName) {
this.namespaceName = namespaceName;
}

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}

public String getClusterName() {
return clusterName;
}

public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}

public String getEnvName() {
return envName;
}

public void setEnvName(String envName) {
this.envName = envName;
}

public int getInstanceCount() {
return instanceCount;
}

public void setInstanceCount(int instanceCount) {
this.instanceCount = instanceCount;
}

public int getBranchInstanceCount() {
return branchInstanceCount;
}

public void setBranchInstanceCount(int branchInstanceCount) {
this.branchInstanceCount = branchInstanceCount;
}

public int getLinkedNamespaceCount() {
return linkedNamespaceCount;
}

public void setLinkedNamespaceCount(int linkedNamespaceCount) {
this.linkedNamespaceCount = linkedNamespaceCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.Set;

@Service
public class AppNamespaceService {

Expand Down Expand Up @@ -254,4 +253,5 @@ public AppNamespace deleteAppNamespace(String appId, String namespaceName) {
public void batchDeleteByAppId(String appId, String operator) {
appNamespaceRepository.batchDeleteByAppId(appId, operator);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.ctrip.framework.apollo.portal.service;

import com.ctrip.framework.apollo.common.constants.GsonType;
import com.ctrip.framework.apollo.common.dto.ClusterDTO;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.dto.NamespaceDTO;
import com.ctrip.framework.apollo.common.dto.PageDTO;
Expand All @@ -28,20 +29,23 @@
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.core.utils.StringUtils;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI.NamespaceAPI;
import com.ctrip.framework.apollo.portal.component.PortalSettings;
import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
import com.ctrip.framework.apollo.portal.constant.RoleType;
import com.ctrip.framework.apollo.portal.constant.TracerEventType;
import com.ctrip.framework.apollo.portal.enricher.adapter.BaseDtoUserInfoEnrichedAdapter;
import com.ctrip.framework.apollo.portal.entity.bo.ItemBO;
import com.ctrip.framework.apollo.portal.entity.bo.NamespaceBO;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceUsage;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.ctrip.framework.apollo.portal.spi.UserInfoHolder;
import com.ctrip.framework.apollo.portal.util.RoleUtils;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
Expand Down Expand Up @@ -80,19 +84,21 @@ public class NamespaceService {
private final NamespaceBranchService branchService;
private final RolePermissionService rolePermissionService;
private final AdditionalUserInfoEnrichService additionalUserInfoEnrichService;
private final ClusterService clusterService;

public NamespaceService(
final PortalConfig portalConfig,
final PortalSettings portalSettings,
final UserInfoHolder userInfoHolder,
final AdminServiceAPI.NamespaceAPI namespaceAPI,
final NamespaceAPI namespaceAPI,
final ItemService itemService,
final ReleaseService releaseService,
final AppNamespaceService appNamespaceService,
final InstanceService instanceService,
final @Lazy NamespaceBranchService branchService,
final RolePermissionService rolePermissionService,
final AdditionalUserInfoEnrichService additionalUserInfoEnrichService) {
final AdditionalUserInfoEnrichService additionalUserInfoEnrichService,
ClusterService clusterService) {
this.portalConfig = portalConfig;
this.portalSettings = portalSettings;
this.userInfoHolder = userInfoHolder;
Expand All @@ -104,6 +110,7 @@ public NamespaceService(
this.branchService = branchService;
this.rolePermissionService = rolePermissionService;
this.additionalUserInfoEnrichService = additionalUserInfoEnrichService;
this.clusterService = clusterService;
}


Expand All @@ -124,35 +131,46 @@ public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) {
}


@Transactional
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName) {

public List<NamespaceUsage> getNamespaceUsageByAppId(String appId, String namespaceName) {
List<Env> envs = portalSettings.getActiveEnvs();
AppNamespace appNamespace = appNamespaceService.findByAppIdAndName(appId, namespaceName);
List<NamespaceUsage> usages = new ArrayList<>();
for (Env env : envs) {
List<ClusterDTO> clusters = clusterService.findClusters(env, appId);
for (ClusterDTO cluster : clusters) {
String clusterName = cluster.getName();
NamespaceUsage usage = this.getNamespaceUsageByEnv(appId, namespaceName, env, clusterName);
if (appNamespace != null && appNamespace.isPublic()) {
int associatedNamespace = this.getPublicAppNamespaceHasAssociatedNamespace(namespaceName, env);
usage.setLinkedNamespaceCount(associatedNamespace);
}

//1. check parent namespace has not instances
if (namespaceHasInstances(appId, env, clusterName, namespaceName)) {
throw new BadRequestException(
"Can not delete namespace because namespace has active instances");
if(usage.getLinkedNamespaceCount() > 0 || usage.getBranchInstanceCount() > 0 || usage.getInstanceCount() > 0) {
usages.add(usage);
}
}
}
return usages;
}

//2. check child namespace has not instances
NamespaceDTO childNamespace = branchService
.findBranchBaseInfo(appId, env, clusterName, namespaceName);
if (childNamespace != null &&
namespaceHasInstances(appId, env, childNamespace.getClusterName(), namespaceName)) {
throw new BadRequestException(
"Can not delete namespace because namespace's branch has active instances");
}
public NamespaceUsage getNamespaceUsageByEnv(String appId, String namespaceName, Env env, String clusterName) {
NamespaceUsage namespaceUsage = new NamespaceUsage(namespaceName, appId, clusterName, env.getName());
int instanceCount = instanceService.getInstanceCountByNamespace(appId, env, clusterName, namespaceName);
namespaceUsage.setInstanceCount(instanceCount);

//3. check public namespace has not associated namespace
if (appNamespace != null && appNamespace.isPublic() && publicAppNamespaceHasAssociatedNamespace(
namespaceName, env)) {
throw new BadRequestException(
"Can not delete public namespace which has associated namespaces");
NamespaceDTO branchNamespace = branchService.findBranchBaseInfo(appId, env, clusterName, namespaceName);
if(branchNamespace != null){
String branchClusterName = branchNamespace.getClusterName();
int branchInstanceCount = instanceService.getInstanceCountByNamespace(appId, env, branchClusterName, namespaceName);
namespaceUsage.setBranchInstanceCount(branchInstanceCount);
}
return namespaceUsage;
}

String operator = userInfoHolder.getUser().getUserId();
@Transactional
public void deleteNamespace(String appId, Env env, String clusterName, String namespaceName) {

String operator = userInfoHolder.getUser().getUserId();
namespaceAPI.deleteNamespace(env, appId, clusterName, namespaceName, operator);
}

Expand Down Expand Up @@ -236,13 +254,12 @@ public NamespaceBO loadNamespaceBO(String appId, Env env, String clusterName,
return transformNamespace2BO(env, namespace);
}

public boolean namespaceHasInstances(String appId, Env env, String clusterName,
String namespaceName) {
return instanceService.getInstanceCountByNamespace(appId, env, clusterName, namespaceName) > 0;
public boolean publicAppNamespaceHasAssociatedNamespace(String publicNamespaceName, Env env) {
return getPublicAppNamespaceHasAssociatedNamespace(publicNamespaceName, env) > 0;
}

public boolean publicAppNamespaceHasAssociatedNamespace(String publicNamespaceName, Env env) {
return namespaceAPI.countPublicAppNamespaceAssociatedNamespaces(env, publicNamespaceName) > 0;
public int getPublicAppNamespaceHasAssociatedNamespace(String publicNamespaceName, Env env) {
return namespaceAPI.countPublicAppNamespaceAssociatedNamespaces(env, publicNamespaceName);
}

public NamespaceBO findPublicNamespaceForAssociatedNamespace(Env env, String appId,
Expand Down
14 changes: 10 additions & 4 deletions apollo-portal/src/main/resources/static/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
"Common.Department": "Department",
"Common.Cluster": "Cluster",
"Common.Environment": "Environment",
"Common.GrayscaleInstance": "GrayscaleInstance",
"Common.Instance": "Instance",
"Common.Email": "Email",
"Common.AppId": "App Id",
"Common.Namespace": "Namespace",
"Common.LinkedNamespace": "LinkedNamespace",
"Common.AppName": "App Name",
"Common.AppOwner": "App Owner",
"Common.AppOwnerLong": "App Owner",
Expand All @@ -40,9 +43,12 @@
"Common.LoginExpiredTips": "Your login is expired. Please refresh the page and try again.",
"Common.Operation": "Operation",
"Common.Delete": "Delete",
"Common.ForceDelete": "Force Delete",
"Component.DeleteNamespace.Title": "Delete Namespace",
"Component.DeleteNamespace.PublicContent": "Deleting namespace will cause the instances unable to get the configuration of this namespace. Are you sure to delete it?",
"Component.DeleteNamespace.PrivateContent": "Deleting a private Namespace will cause the instances unable to get the configuration of this namespace, and the page will prompt 'missing namespace' (unless the AppNamespace is deleted by admin tool). Are you sure to delete it?",
"Component.DeleteNamespace.PublicContent": "Caution, the public namespace for all environments will be deleted! This will cause the instances unable to get the configuration of this namespace. Are you sure you want to delete it?",
"Component.DeleteNamespace.PrivateContent": "Caution, the private namespace for all environments will be deleted! This will cause the instances unable to get the configuration of this namespace. Are you sure you want to delete it?",
"Component.DeleteNamespace.LinkedContent": "Caution, all the namespaces associated with the current environment will be deleted! This will cause the instances unable to get the configuration of this namespace. Are you sure you want to delete it?",
"Component.DeleteNamespace.ForceDeleteContent": "There are instances in use for the current namespace within 24 hours, are you sure to force delete the namespace?",
"Component.GrayscalePublishRule.Title": "Edit Grayscale Rule",
"Component.GrayscalePublishRule.AppId": "Grayscale AppId",
"Component.GrayscalePublishRule.AcceptRule": "Grayscale Application Rule",
Expand Down Expand Up @@ -428,8 +434,8 @@
"Delete.ClusterNameTips": "(Please query cluster information before deletion)",
"Delete.ClusterInfo": "Cluster information",
"Delete.DeleteNamespace": "Delete AppNamespace",
"Delete.DeleteNamespaceTips": "(Note that Namespace and AppNamespace in all environments will be deleted! If you just want to delete the namespace of some environment, let the user delete it on the project page!",
"Delete.DeleteNamespaceTips2": "Currently users can delete the associated namespace and private namespace by themselves, but they can not delete the AppNamespace. Because deleting AppNamespace has very large impacts, it is only allowed to be deleted by system administrators for the time being. For public Namespace, it is necessary to ensure that no application associates the AppNamespace",
"Delete.DeleteNamespaceTips": "(Note that Namespace and AppNamespace in all environments will be deleted!",
"Delete.DeleteNamespaceTips2": "For public Namespace, it is necessary to ensure that no application associates the AppNamespace",
"Delete.AppNamespaceName": "AppNamespace name",
"Delete.AppNamespaceNameTips": "(For non-properties namespaces, please add the suffix, such as apollo.xml)",
"Delete.AppNamespaceInfo": "AppNamespace Information",
Expand Down
Loading