Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,21 @@
*/
package com.ctrip.framework.apollo.openapi.server.service;

import com.ctrip.framework.apollo.openapi.model.MultiResponseEntity;
import com.ctrip.framework.apollo.openapi.model.OpenAppDTO;
import com.ctrip.framework.apollo.openapi.model.OpenCreateAppDTO;
import com.ctrip.framework.apollo.openapi.model.OpenEnvClusterDTO;
import com.ctrip.framework.apollo.openapi.model.OpenEnvClusterInfo;
import com.ctrip.framework.apollo.openapi.model.OpenMissEnvDTO;
import org.springframework.lang.NonNull;

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

public interface AppOpenApiService {

void createApp(@NonNull OpenCreateAppDTO req);
OpenAppDTO createApp(@NonNull OpenCreateAppDTO req);

List<OpenEnvClusterDTO> getEnvClusterInfo(String appId);
List<OpenEnvClusterDTO> getEnvClusters(String appId);

List<OpenAppDTO> getAllApps();

Expand All @@ -39,13 +40,13 @@ public interface AppOpenApiService {

void updateApp(OpenAppDTO openAppDTO);

List<OpenAppDTO> getAppsBySelf(Set<String> appIds, Integer page, Integer size);
List<OpenAppDTO> getAppsWithPageAndSize(Set<String> appIds, Integer page, Integer size);

void createAppInEnv(String env, OpenAppDTO app, String operator);
void createAppInEnv(String env, OpenAppDTO app);

OpenAppDTO deleteApp(String appId);

MultiResponseEntity findMissEnvs(String appId);
List<OpenMissEnvDTO> findMissEnvs(String appId);

MultiResponseEntity getAppNavTree(String appId);
List<OpenEnvClusterInfo> getEnvClusterInfos(String appId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2025 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.openapi.server.service;

import com.ctrip.framework.apollo.openapi.model.OpenInstanceDTO;
import com.ctrip.framework.apollo.openapi.model.OpenInstancePageDTO;

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

public interface InstanceOpenApiService {

int getInstanceCountByNamespace(String appId, String env, String clusterName,
String namespaceName);

OpenInstancePageDTO getByRelease(String env, long releaseId, int page, int size);

List<OpenInstanceDTO> getByReleasesNotIn(String env, String appId, String clusterName,
String namespaceName, Set<Long> releaseIds);

OpenInstancePageDTO getByNamespace(String env, String appId, String clusterName,
String namespaceName, String instanceAppId, Integer page, Integer size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
import com.ctrip.framework.apollo.openapi.model.OpenAppDTO;
import com.ctrip.framework.apollo.openapi.model.OpenCreateAppDTO;
import com.ctrip.framework.apollo.openapi.model.OpenEnvClusterDTO;
import com.ctrip.framework.apollo.openapi.model.MultiResponseEntity;
import com.ctrip.framework.apollo.openapi.model.OpenEnvClusterInfo;
import com.ctrip.framework.apollo.openapi.model.RichResponseEntity;
import com.ctrip.framework.apollo.openapi.model.OpenMissEnvDTO;
import com.ctrip.framework.apollo.openapi.util.OpenApiModelConverters;
import com.ctrip.framework.apollo.portal.component.PortalSettings;
import com.ctrip.framework.apollo.portal.component.UserIdentityContextHolder;
import com.ctrip.framework.apollo.portal.entity.model.AppModel;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.ctrip.framework.apollo.portal.listener.AppDeletionEvent;
Expand Down Expand Up @@ -83,17 +83,17 @@ private App convert(OpenAppDTO dto) {
* @see com.ctrip.framework.apollo.portal.controller.AppController#create(AppModel)
*/
@Override
public void createApp(OpenCreateAppDTO req) {
public OpenAppDTO createApp(OpenCreateAppDTO req) {
App app = convert(req.getApp());
List<String> admins = req.getAdmins();
Set<String> admins = req.getAdmins();
if (admins == null) {
admins = Collections.emptyList();
admins = Collections.emptySet();
}
appService.createAppAndAddRolePermission(app, new HashSet<>(admins));
return OpenApiModelConverters.fromApp(appService.createAppAndAddRolePermission(app, admins));
}

@Override
public List<OpenEnvClusterDTO> getEnvClusterInfo(String appId) {
public List<OpenEnvClusterDTO> getEnvClusters(String appId) {
List<OpenEnvClusterDTO> envClusters = new LinkedList<>();

List<Env> envs = portalSettings.getActiveEnvs();
Expand Down Expand Up @@ -134,6 +134,7 @@ public List<OpenAppDTO> getAuthorizedApps() {

/**
* Updating Application Information - Using OpenAPI DTOs
*
* @param openAppDTO OpenAPI application DTO
*/
@Override
Expand All @@ -145,11 +146,12 @@ public void updateApp(OpenAppDTO openAppDTO) {

/**
* Get the current user's app list (paginated)
*
* @param page Pagination parameter
* @return App list
*/
@Override
public List<OpenAppDTO> getAppsBySelf(Set<String> appIds, Integer page, Integer size) {
public List<OpenAppDTO> getAppsWithPageAndSize(Set<String> appIds, Integer page, Integer size) {
int pageIndex = page == null ? 0 : page;
int pageSize = (size == null || size <= 0) ? 20 : size;
Pageable pageable = Pageable.ofSize(pageSize).withPage(pageIndex);
Expand All @@ -163,12 +165,12 @@ public List<OpenAppDTO> getAppsBySelf(Set<String> appIds, Integer page, Integer

/**
* Create an application in a specified environment
*
* @param env Environment
* @param app Application information
* @param operator Operator
*/
@Override
public void createAppInEnv(String env, OpenAppDTO app, String operator) {
public void createAppInEnv(String env, OpenAppDTO app) {
if (env == null) {
throw BadRequestException.invalidEnvFormat("null");
}
Expand All @@ -179,14 +181,16 @@ public void createAppInEnv(String env, OpenAppDTO app, String operator) {
throw BadRequestException.invalidEnvFormat(env);
}
App appEntity = convert(app);
appService.createAppInRemote(envEnum, appEntity);
appService.createAppInRemoteNew(envEnum, appEntity);

roleInitializationService.initNamespaceSpecificEnvRoles(appEntity.getAppId(),
ConfigConsts.NAMESPACE_APPLICATION, env, operator);
ConfigConsts.NAMESPACE_APPLICATION, env,
UserIdentityContextHolder.getOperator().getUserId());
}

/**
* Delete an application
*
* @param appId application ID
* @return the deleted application
*/
Expand All @@ -199,56 +203,57 @@ public OpenAppDTO deleteApp(String appId) {

/**
* Find missing environments
*
* @param appId application ID
* @return list of missing environments
*/
public MultiResponseEntity findMissEnvs(String appId) {
List<RichResponseEntity> entities = new ArrayList<>();
MultiResponseEntity response = new MultiResponseEntity(HttpStatus.OK.value(), entities);
public List<OpenMissEnvDTO> findMissEnvs(String appId) {
List<OpenMissEnvDTO> missEnvs = new ArrayList<>();

for (Env env : portalSettings.getActiveEnvs()) {
try {
appService.load(env, appId);
} catch (Exception e) {
RichResponseEntity entity;
OpenMissEnvDTO missEnv = new OpenMissEnvDTO();
if (e instanceof HttpClientErrorException
&& ((HttpClientErrorException) e).getStatusCode() == HttpStatus.NOT_FOUND) {
entity = new RichResponseEntity(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase());
entity.setBody(env.toString());
missEnv.setCode(HttpStatus.OK.value());
missEnv.setMessage(env.toString());
} else {
entity = new RichResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(),
"load env:" + env.getName() + " cluster error." + e.getMessage());
missEnv.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
missEnv.setMessage(
String.format("load appId:%s from env %s error.", appId, env) + e.getMessage());
}
response.addEntitiesItem(entity);
missEnvs.add(missEnv);
}
}
return response;
return missEnvs;
}

/**
* Find AppNavTree
*
* @param appId
* @return list of EnvClusterInfos
*/
@Override
public MultiResponseEntity getAppNavTree(String appId) {
List<RichResponseEntity> entities = new ArrayList<>();
MultiResponseEntity response = new MultiResponseEntity(HttpStatus.OK.value(), entities);
public List<OpenEnvClusterInfo> getEnvClusterInfos(String appId) {
List<OpenEnvClusterInfo> envClusterInfos = new ArrayList<>();
List<Env> envs = portalSettings.getActiveEnvs();
for (Env env : envs) {
try {
OpenEnvClusterInfo openEnvClusterInfo =
OpenApiModelConverters.fromEnvClusterInfo(appService.createEnvNavNode(env, appId));
RichResponseEntity entity =
new RichResponseEntity(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase());
entity.setBody(openEnvClusterInfo);
response.addEntitiesItem(entity);
openEnvClusterInfo.setCode(HttpStatus.OK.value());
envClusterInfos.add(openEnvClusterInfo);
} catch (Exception e) {
logger.warn("Failed to load env {} navigation for app {}", env, appId, e);
RichResponseEntity entity = new RichResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(),
"load env:" + env.getName() + " cluster error." + e.getMessage());
response.addEntitiesItem(entity);
OpenEnvClusterInfo envClusterInfo = new OpenEnvClusterInfo();
envClusterInfo.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
envClusterInfo.setEnv(env.getName());
envClusterInfo.setMessage("load env:" + env.getName() + " cluster error." + e.getMessage());
envClusterInfos.add(envClusterInfo);
}
}
return response;
return envClusterInfos;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,22 @@
*/
package com.ctrip.framework.apollo.openapi.server.service;

import com.ctrip.framework.apollo.openapi.api.InstanceOpenApiService;
import com.ctrip.framework.apollo.common.dto.InstanceConfigDTO;
import com.ctrip.framework.apollo.common.dto.InstanceDTO;
import com.ctrip.framework.apollo.common.dto.PageDTO;
import com.ctrip.framework.apollo.openapi.model.OpenInstanceDTO;
import com.ctrip.framework.apollo.openapi.model.OpenInstancePageDTO;
import com.ctrip.framework.apollo.openapi.util.OpenApiModelConverters;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.ctrip.framework.apollo.portal.service.InstanceService;
import java.util.Collections;
import java.util.Date;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

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

@Service
public class ServerInstanceOpenApiService implements InstanceOpenApiService {

Expand All @@ -36,4 +47,67 @@ public int getInstanceCountByNamespace(String appId, String env, String clusterN
return instanceService.getInstanceCountByNamespace(appId, Env.valueOf(env), clusterName,
namespaceName);
}

/**
* Query instances by release version (supports pagination) - returns OpenAPI DTO
*/
@Override
public OpenInstancePageDTO getByRelease(String env, long releaseId, int page, int size) {
PageDTO<InstanceDTO> portalPageDTO =
instanceService.getByRelease(Env.valueOf(env), releaseId, page, size);
// PageDTO<InstanceDTO> portalPageDTO = mockPortalPageDTO(page, size);

return transformToOpenPageDTO(portalPageDTO);
}

/**
* Query instances not in a specified release - returns an OpenAPI DTO
*/
@Override
public List<OpenInstanceDTO> getByReleasesNotIn(String env, String appId, String clusterName,
String namespaceName, Set<Long> releaseIds) {
List<InstanceDTO> portalInstances = instanceService.getByReleasesNotIn(Env.valueOf(env), appId,
clusterName, namespaceName, releaseIds);
return OpenApiModelConverters.fromInstanceDTOs(portalInstances);
}

@Override
public OpenInstancePageDTO getByNamespace(String env, String appId, String clusterName,
String namespaceName, String instanceAppId, Integer page, Integer size) {
// return transformToOpenPageDTO((mockPortalPageDTO(page,size)));
return transformToOpenPageDTO(instanceService.getByNamespace(Env.valueOf(env), appId,
clusterName, namespaceName, instanceAppId, page, size));
}

/**
* Convert PageDTO<InstanceDTO> to OpenPageDTOOpenInstanceDTO
*/
private OpenInstancePageDTO transformToOpenPageDTO(PageDTO<InstanceDTO> pageDTO) {
List<OpenInstanceDTO> instances = OpenApiModelConverters.fromInstanceDTOs(pageDTO.getContent());
OpenInstancePageDTO openInstancePageDTO = new OpenInstancePageDTO();
openInstancePageDTO.setPage(pageDTO.getPage());
openInstancePageDTO.setSize(pageDTO.getSize());
openInstancePageDTO.setTotal(pageDTO.getTotal());
openInstancePageDTO.setInstances(instances);

return openInstancePageDTO;
}

private PageDTO<InstanceDTO> mockPortalPageDTO(int page, int size) {
InstanceConfigDTO config = new InstanceConfigDTO();
config.setReleaseDeliveryTime(new Date());
config.setDataChangeLastModifiedTime(new Date());

InstanceDTO instance = new InstanceDTO();
instance.setId(1L);
instance.setAppId("mock-app");
instance.setClusterName("default");
instance.setDataCenter("SHA");
instance.setIp("10.0.0.1");
instance.setConfigs(Collections.singletonList(config));

return new PageDTO<>(Collections.singletonList(instance), PageRequest.of(page, size), 1 // mock
// 总数
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs;
import com.ctrip.framework.apollo.portal.entity.vo.NamespaceIdentifier;
import com.ctrip.framework.apollo.portal.entity.vo.Organization;
import com.ctrip.framework.apollo.portal.environment.Env;
import com.google.common.base.Preconditions;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
Expand All @@ -72,8 +73,8 @@
import java.util.stream.Collectors;

/**
* Non-invasive converters for OpenAPI generated model classes.
* This class mirrors/OpenApiBeanUtils functions but targets com.ctrip.framework.apollo.openapi.model.* types.
* Non-invasive converters for OpenAPI generated model classes. This class mirrors/OpenApiBeanUtils
* functions but targets com.ctrip.framework.apollo.openapi.model.* types.
*/
public final class OpenApiModelConverters {

Expand Down Expand Up @@ -397,7 +398,17 @@ public static List<OpenInstanceDTO> fromInstanceDTOs(final List<InstanceDTO> ins
// newly added
public static OpenEnvClusterInfo fromEnvClusterInfo(final EnvClusterInfo envClusterInfo) {
Preconditions.checkArgument(envClusterInfo != null);
return BeanUtils.transform(OpenEnvClusterInfo.class, envClusterInfo);
OpenEnvClusterInfo openEnvClusterInfo = new OpenEnvClusterInfo();
Env env = envClusterInfo.getEnv();
if (env != null) {
openEnvClusterInfo.setEnv(env.toString());
}
List<ClusterDTO> clusters = envClusterInfo.getClusters();
if (!CollectionUtils.isEmpty(clusters)) {
openEnvClusterInfo.setClusters(clusters.stream().map(OpenApiModelConverters::fromClusterDTO)
.collect(Collectors.toList()));
}
return openEnvClusterInfo;
}

// newly added
Expand Down
Loading