content: 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();
      }
  
    }
  
  }
  