package com.ctrip.framework.apollo.portal.controller; import com.google.common.collect.Sets; import com.ctrip.framework.apollo.common.entity.App; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.common.http.MultiResponseEntity; import com.ctrip.framework.apollo.common.http.RichResponseEntity; import com.ctrip.framework.apollo.common.utils.InputValidator; import com.ctrip.framework.apollo.common.utils.RequestPrecondition; import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.portal.component.PortalSettings; import com.ctrip.framework.apollo.portal.entity.model.AppModel; import com.ctrip.framework.apollo.portal.entity.vo.EnvClusterInfo; import com.ctrip.framework.apollo.portal.listener.AppCreationEvent; import com.ctrip.framework.apollo.portal.listener.AppInfoChangedEvent; import com.ctrip.framework.apollo.portal.service.AppService; import com.ctrip.framework.apollo.portal.service.RolePermissionService; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import com.ctrip.framework.apollo.portal.util.RoleUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; import java.util.List; import java.util.Objects; import java.util.Set; @RestController @RequestMapping("/apps") public class AppController { @Autowired private UserInfoHolder userInfoHolder; @Autowired private AppService appService; @Autowired private PortalSettings portalSettings; @Autowired private ApplicationEventPublisher publisher; @Autowired private RolePermissionService rolePermissionService; @RequestMapping(value = "", method = RequestMethod.GET) public List<App> findApps(@RequestParam(value = "appIds", required = false) String appIds) { if (StringUtils.isEmpty(appIds)) { return appService.findAll(); } else { return appService.findByAppIds(Sets.newHashSet(appIds.split(","))); } } @RequestMapping(value = "/by-owner", method = RequestMethod.GET) public List<App> findAppsByOwner(@RequestParam("owner") String owner, Pageable page) { return appService.findByOwnerName(owner, page); } @RequestMapping(value = "", method = RequestMethod.POST) public App create(@RequestBody AppModel appModel) { App app = transformToApp(appModel); App createdApp = appService.createAppInLocal(app); publisher.publishEvent(new AppCreationEvent(createdApp)); Set<String> admins = appModel.getAdmins(); if (!CollectionUtils.isEmpty(admins)) { rolePermissionService.assignRoleToUsers(RoleUtils.buildAppMasterRoleName(createdApp.getAppId()), admins, userInfoHolder.getUser().getUserId()); } return createdApp; } @PreAuthorize(value = "@permissionValidator.isAppAdmin(#appId)") @RequestMapping(value = "/{appId}", method = RequestMethod.PUT) public void update(@PathVariable String appId, @RequestBody AppModel appModel) { if (!Objects.equals(appId, appModel.getAppId())) { throw new BadRequestException("The App Id of path variable and request body is different"); } App app = transformToApp(appModel); App updatedApp = appService.updateAppInLocal(app); publisher.publishEvent(new AppInfoChangedEvent(updatedApp)); } @RequestMapping(value = "/{appId}/navtree", method = RequestMethod.GET) public MultiResponseEntity<EnvClusterInfo> nav(@PathVariable String appId) { MultiResponseEntity<EnvClusterInfo> response = MultiResponseEntity.ok(); List<Env> envs = portalSettings.getActiveEnvs(); for (Env env : envs) { try { response.addResponseEntity(RichResponseEntity.ok(appService.createEnvNavNode(env, appId))); } catch (Exception e) { response.addResponseEntity(RichResponseEntity.error(HttpStatus.INTERNAL_SERVER_ERROR, "load env:" + env.name() + " cluster error." + e .getMessage())); } } return response; } @RequestMapping(value = "/envs/{env}", method = RequestMethod.POST, consumes = { "application/json"}) public ResponseEntity<Void> create(@PathVariable String env, @RequestBody App app) { RequestPrecondition.checkArgumentsNotEmpty(app.getName(), app.getAppId(), app.getOwnerEmail(), app.getOwnerName(), app.getOrgId(), app.getOrgName()); if (!InputValidator.isValidClusterNamespace(app.getAppId())) { throw new BadRequestException(InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE); } appService.createAppInRemote(Env.valueOf(env), app); return ResponseEntity.ok().build(); } @RequestMapping(value = "/{appId}", method = RequestMethod.GET) public App load(@PathVariable String appId) { return appService.load(appId); } @RequestMapping(value = "/{appId}/miss_envs", method = RequestMethod.GET) public MultiResponseEntity<Env> findMissEnvs(@PathVariable String appId) { MultiResponseEntity<Env> response = MultiResponseEntity.ok(); for (Env env : portalSettings.getActiveEnvs()) { try { appService.load(env, appId); } catch (Exception e) { if (e instanceof HttpClientErrorException && ((HttpClientErrorException) e).getStatusCode() == HttpStatus.NOT_FOUND) { response.addResponseEntity(RichResponseEntity.ok(env)); } else { response.addResponseEntity(RichResponseEntity.error(HttpStatus.INTERNAL_SERVER_ERROR, String.format("load appId:%s from env %s error.", appId, env) + e.getMessage())); } } } return response; } private App transformToApp(AppModel appModel) { String appId = appModel.getAppId(); String appName = appModel.getName(); String ownerName = appModel.getOwnerName(); String orgId = appModel.getOrgId(); String orgName = appModel.getOrgName(); RequestPrecondition.checkArgumentsNotEmpty(appId, appName, ownerName, orgId, orgName); if (!InputValidator.isValidClusterNamespace(appModel.getAppId())) { throw new BadRequestException(String.format("AppId格式错误: %s", InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE)); } App app = new App(); app.setAppId(appId); app.setName(appName); app.setOwnerName(ownerName); app.setOrgId(orgId); app.setOrgName(orgName); return app; } }