package com.ctrip.framework.apollo.portal.api; import com.google.common.base.Joiner; import com.ctrip.framework.apollo.common.dto.AppDTO; import com.ctrip.framework.apollo.common.dto.AppNamespaceDTO; import com.ctrip.framework.apollo.common.dto.ClusterDTO; import com.ctrip.framework.apollo.common.dto.CommitDTO; import com.ctrip.framework.apollo.common.dto.GrayReleaseRuleDTO; import com.ctrip.framework.apollo.common.dto.InstanceDTO; import com.ctrip.framework.apollo.common.dto.ItemChangeSets; import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.dto.NamespaceDTO; import com.ctrip.framework.apollo.common.dto.NamespaceLockDTO; import com.ctrip.framework.apollo.common.dto.PageDTO; import com.ctrip.framework.apollo.common.dto.ReleaseDTO; import com.ctrip.framework.apollo.common.dto.ReleaseHistoryDTO; import com.ctrip.framework.apollo.core.enums.Env; import org.springframework.boot.actuate.health.Health; import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @Service public class AdminServiceAPI { @Service public static class HealthAPI extends API { public Health health(Env env) { return restTemplate.get(env, "/health", Health.class); } } @Service public static class AppAPI extends API { public AppDTO loadApp(Env env, String appId) { return restTemplate.get(env, "apps/{appId}", AppDTO.class, appId); } public AppDTO createApp(Env env, AppDTO app) { return restTemplate.post(env, "apps", app, AppDTO.class); } public void updateApp(Env env, AppDTO app) { restTemplate.put(env, "apps/{appId}", app, app.getAppId()); } } @Service public static class NamespaceAPI extends API { private ParameterizedTypeReference<Map<String, Boolean>> typeReference = new ParameterizedTypeReference<Map<String, Boolean>>() { }; public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env, String clusterName) { NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces", NamespaceDTO[].class, appId, clusterName); return Arrays.asList(namespaceDTOs); } public NamespaceDTO loadNamespace(String appId, Env env, String clusterName, String namespaceName) { return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}", NamespaceDTO.class, appId, clusterName, namespaceName); } public NamespaceDTO findPublicNamespaceForAssociatedNamespace(Env env, String appId, String clusterName, String namespaceName) { return restTemplate .get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/associated-public-namespace", NamespaceDTO.class, appId, clusterName, namespaceName); } public NamespaceDTO createNamespace(Env env, NamespaceDTO namespace) { return restTemplate .post(env, "apps/{appId}/clusters/{clusterName}/namespaces", namespace, NamespaceDTO.class, namespace.getAppId(), namespace.getClusterName()); } public AppNamespaceDTO createAppNamespace(Env env, AppNamespaceDTO appNamespace) { return restTemplate .post(env, "apps/{appId}/appnamespaces", appNamespace, AppNamespaceDTO.class, appNamespace.getAppId()); } public void deleteNamespace(Env env, String appId, String clusterName, String namespaceName, String operator) { restTemplate .delete(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}?operator={operator}", appId, clusterName, namespaceName, operator); } public Map<String, Boolean> getNamespacePublishInfo(Env env, String appId) { return restTemplate.get(env, "apps/{appId}/namespaces/publish_info", typeReference, appId).getBody(); } public List<NamespaceDTO> getPublicAppNamespaceAllNamespaces(Env env, String publicNamespaceName, int page, int size) { NamespaceDTO[] namespaceDTOs = restTemplate.get(env, "/appnamespaces/{publicNamespaceName}/namespaces?page={page}&size={size}", NamespaceDTO[].class, publicNamespaceName, page, size); return Arrays.asList(namespaceDTOs); } public int countPublicAppNamespaceAssociatedNamespaces(Env env, String publicNamesapceName) { Integer count = restTemplate.get(env, "/appnamespaces/{publicNamespaceName}/associated-namespaces/count", Integer.class, publicNamesapceName); return count == null ? 0 : count; } } @Service public static class ItemAPI extends API { public List<ItemDTO> findItems(String appId, Env env, String clusterName, String namespaceName) { ItemDTO[] itemDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", ItemDTO[].class, appId, clusterName, namespaceName); return Arrays.asList(itemDTOs); } public ItemDTO loadItem(Env env, String appId, String clusterName, String namespaceName, String key) { return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{key}", ItemDTO.class, appId, clusterName, namespaceName, key); } public void updateItemsByChangeSet(String appId, Env env, String clusterName, String namespace, ItemChangeSets changeSets) { restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/itemset", changeSets, Void.class, appId, clusterName, namespace); } public void updateItem(String appId, Env env, String clusterName, String namespace, long itemId, ItemDTO item) { restTemplate.put(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", item, appId, clusterName, namespace, itemId); } public ItemDTO createItem(String appId, Env env, String clusterName, String namespace, ItemDTO item) { return restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/items", item, ItemDTO.class, appId, clusterName, namespace); } public void deleteItem(Env env, long itemId, String operator) { restTemplate.delete(env, "items/{itemId}?operator={operator}", itemId, operator); } } @Service public static class ClusterAPI extends API { public List<ClusterDTO> findClustersByApp(String appId, Env env) { ClusterDTO[] clusterDTOs = restTemplate.get(env, "apps/{appId}/clusters", ClusterDTO[].class, appId); return Arrays.asList(clusterDTOs); } public ClusterDTO loadCluster(String appId, Env env, String clusterName) { return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}", ClusterDTO.class, appId, clusterName); } public boolean isClusterUnique(String appId, Env env, String clusterName) { return restTemplate .get(env, "apps/{appId}/cluster/{clusterName}/unique", Boolean.class, appId, clusterName); } public ClusterDTO create(Env env, ClusterDTO cluster) { return restTemplate.post(env, "apps/{appId}/clusters", cluster, ClusterDTO.class, cluster.getAppId()); } public void delete(Env env, String appId, String clusterName, String operator) { restTemplate.delete(env, "apps/{appId}/clusters/{clusterName}?operator={operator}", appId, clusterName, operator); } } @Service public static class ReleaseAPI extends API { private static final Joiner JOINER = Joiner.on(","); public ReleaseDTO loadRelease(Env env, long releaseId) { return restTemplate.get(env, "releases/{releaseId}", ReleaseDTO.class, releaseId); } public List<ReleaseDTO> findReleaseByIds(Env env, Set<Long> releaseIds) { if (CollectionUtils.isEmpty(releaseIds)) { return Collections.emptyList(); } ReleaseDTO[] releases = restTemplate.get(env, "/releases?releaseIds={releaseIds}", ReleaseDTO[].class, JOINER.join(releaseIds)); return Arrays.asList(releases); } public List<ReleaseDTO> findAllReleases(String appId, Env env, String clusterName, String namespaceName, int page, int size) { ReleaseDTO[] releaseDTOs = restTemplate.get( env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/all?page={page}&size={size}", ReleaseDTO[].class, appId, clusterName, namespaceName, page, size); return Arrays.asList(releaseDTOs); } public List<ReleaseDTO> findActiveReleases(String appId, Env env, String clusterName, String namespaceName, int page, int size) { ReleaseDTO[] releaseDTOs = restTemplate.get( env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/active?page={page}&size={size}", ReleaseDTO[].class, appId, clusterName, namespaceName, page, size); return Arrays.asList(releaseDTOs); } public ReleaseDTO loadLatestRelease(String appId, Env env, String clusterName, String namespace) { ReleaseDTO releaseDTO = restTemplate .get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/latest", ReleaseDTO.class, appId, clusterName, namespace); return releaseDTO; } public ReleaseDTO createRelease(String appId, Env env, String clusterName, String namespace, String releaseName, String releaseComment, String operator, boolean isEmergencyPublish) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType(MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8")); MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>(); parameters.add("name", releaseName); parameters.add("comment", releaseComment); parameters.add("operator", operator); parameters.add("isEmergencyPublish", String.valueOf(isEmergencyPublish)); HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(parameters, headers); ReleaseDTO response = restTemplate.post( env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases", entity, ReleaseDTO.class, appId, clusterName, namespace); return response; } public ReleaseDTO updateAndPublish(String appId, Env env, String clusterName, String namespace, String releaseName, String releaseComment, String branchName, boolean isEmergencyPublish, boolean deleteBranch, ItemChangeSets changeSets) { return restTemplate.post(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/updateAndPublish?" + "releaseName={releaseName}&releaseComment={releaseComment}&branchName={branchName}" + "&deleteBranch={deleteBranch}&isEmergencyPublish={isEmergencyPublish}", changeSets, ReleaseDTO.class, appId, clusterName, namespace, releaseName, releaseComment, branchName, deleteBranch, isEmergencyPublish); } public void rollback(Env env, long releaseId, String operator) { restTemplate.put(env, "releases/{releaseId}/rollback?operator={operator}", null, releaseId, operator); } } @Service public static class CommitAPI extends API { public List<CommitDTO> find(String appId, Env env, String clusterName, String namespaceName, int page, int size) { CommitDTO[] commitDTOs = restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/commit?page={page}&size={size}", CommitDTO[].class, appId, clusterName, namespaceName, page, size); return Arrays.asList(commitDTOs); } } @Service public static class NamespaceLockAPI extends API { public NamespaceLockDTO getNamespaceLockOwner(String appId, Env env, String clusterName, String namespaceName) { return restTemplate.get(env, "apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/lock", NamespaceLockDTO.class, appId, clusterName, namespaceName); } } @Service public static class InstanceAPI extends API { private Joiner joiner = Joiner.on(","); private ParameterizedTypeReference<PageDTO<InstanceDTO>> pageInstanceDtoType = new ParameterizedTypeReference<PageDTO<InstanceDTO>>() { }; public PageDTO<InstanceDTO> getByRelease(Env env, long releaseId, int page, int size) { ResponseEntity<PageDTO<InstanceDTO>> entity = restTemplate .get(env, "/instances/by-release?releaseId={releaseId}&page={page}&size={size}", pageInstanceDtoType, releaseId, page, size); return entity.getBody(); } public List<InstanceDTO> getByReleasesNotIn(String appId, Env env, String clusterName, String namespaceName, Set<Long> releaseIds) { InstanceDTO[] instanceDTOs = restTemplate.get(env, "/instances/by-namespace-and-releases-not-in?appId={appId}&clusterName={clusterName}&namespaceName={namespaceName}&releaseIds={releaseIds}", InstanceDTO[].class, appId, clusterName, namespaceName, joiner.join(releaseIds)); return Arrays.asList(instanceDTOs); } public PageDTO<InstanceDTO> getByNamespace(String appId, Env env, String clusterName, String namespaceName, String instanceAppId, int page, int size) { ResponseEntity<PageDTO<InstanceDTO>> entity = restTemplate.get(env, "/instances/by-namespace?appId={appId}" + "&clusterName={clusterName}&namespaceName={namespaceName}&instanceAppId={instanceAppId}" + "&page={page}&size={size}", pageInstanceDtoType, appId, clusterName, namespaceName, instanceAppId, page, size); return entity.getBody(); } public int getInstanceCountByNamespace(String appId, Env env, String clusterName, String namespaceName) { Integer count = restTemplate.get(env, "/instances/by-namespace/count?appId={appId}&clusterName={clusterName}&namespaceName={namespaceName}", Integer.class, appId, clusterName, namespaceName); if (count == null) { return 0; } return count; } } @Service public static class NamespaceBranchAPI extends API { public NamespaceDTO createBranch(String appId, Env env, String clusterName, String namespaceName, String operator) { return restTemplate .post(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/branches?operator={operator}", null, NamespaceDTO.class, appId, clusterName, namespaceName, operator); } public NamespaceDTO findBranch(String appId, Env env, String clusterName, String namespaceName) { return restTemplate.get(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/branches", NamespaceDTO.class, appId, clusterName, namespaceName); } public GrayReleaseRuleDTO findBranchGrayRules(String appId, Env env, String clusterName, String namespaceName, String branchName) { return restTemplate .get(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules", GrayReleaseRuleDTO.class, appId, clusterName, namespaceName, branchName); } public void updateBranchGrayRules(String appId, Env env, String clusterName, String namespaceName, String branchName, GrayReleaseRuleDTO rules) { restTemplate .put(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules", rules, appId, clusterName, namespaceName, branchName); } public void deleteBranch(String appId, Env env, String clusterName, String namespaceName, String branchName, String operator) { restTemplate.delete(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}?operator={operator}", appId, clusterName, namespaceName, branchName, operator); } } @Service public static class ReleaseHistoryAPI extends API { private ParameterizedTypeReference<PageDTO<ReleaseHistoryDTO>> type = new ParameterizedTypeReference<PageDTO<ReleaseHistoryDTO>>() { }; public PageDTO<ReleaseHistoryDTO> findReleaseHistoriesByNamespace(String appId, Env env, String clusterName, String namespaceName, int page, int size) { return restTemplate.get(env, "/apps/{appId}/clusters/{clusterName}/namespaces/{namespaceName}/releases/histories?page={page}&size={size}", type, appId, clusterName, namespaceName, page, size).getBody(); } public PageDTO<ReleaseHistoryDTO> findByReleaseIdAndOperation(Env env, long releaseId, int operation, int page, int size) { return restTemplate.get(env, "/releases/histories/by_release_id_and_operation?releaseId={releaseId}&operation={operation}&page={page}&size={size}", type, releaseId, operation, page, size).getBody(); } public PageDTO<ReleaseHistoryDTO> findByPreviousReleaseIdAndOperation(Env env, long previousReleaseId, int operation, int page, int size) { return restTemplate.get(env, "/releases/histories/by_previous_release_id_and_operation?previousReleaseId={releaseId}&operation={operation}&page={page}&size={size}", type, previousReleaseId, operation, page, size).getBody(); } } }